Yuki Takei пре 7 месеци
родитељ
комит
0bb9a2088c

+ 48 - 0
apps/app/src/components/PageView/PageView.tsx

@@ -41,6 +41,7 @@ type Props = {
 }
 }
 
 
 export const PageView = (props: Props): JSX.Element => {
 export const PageView = (props: Props): JSX.Element => {
+  const renderStartTime = performance.now();
 
 
   const commentsContainerRef = useRef<HTMLDivElement>(null);
   const commentsContainerRef = useRef<HTMLDivElement>(null);
 
 
@@ -57,6 +58,15 @@ export const PageView = (props: Props): JSX.Element => {
   const [page] = useCurrentPageData();
   const [page] = useCurrentPageData();
   const { data: viewOptions } = useViewOptions();
   const { data: viewOptions } = useViewOptions();
 
 
+  // DEBUG: Log PageView render start
+  console.log('[PAGEVIEW-DEBUG] PageView render started:', {
+    pagePath,
+    currentPageId,
+    pageId: page?._id,
+    timestamp: new Date().toISOString(),
+    renderStartTime,
+  });
+
   const isNotFound = isNotFoundMeta || page == null;
   const isNotFound = isNotFoundMeta || page == null;
   const isUsersHomepagePath = isUsersHomepage(pagePath);
   const isUsersHomepagePath = isUsersHomepage(pagePath);
 
 
@@ -69,13 +79,23 @@ export const PageView = (props: Props): JSX.Element => {
 
 
   // ***************************  Auto Scroll  ***************************
   // ***************************  Auto Scroll  ***************************
   useEffect(() => {
   useEffect(() => {
+    const scrollEffectStartTime = performance.now();
+    console.log('[PAGEVIEW-DEBUG] Auto scroll effect triggered:', {
+      currentPageId,
+      hash: window.location.hash,
+      timestamp: new Date().toISOString(),
+      effectStartTime: scrollEffectStartTime,
+    });
+
     if (currentPageId == null) {
     if (currentPageId == null) {
+      console.log('[PAGEVIEW-DEBUG] Auto scroll skipped - no currentPageId');
       return;
       return;
     }
     }
 
 
     // do nothing if hash is empty
     // do nothing if hash is empty
     const { hash } = window.location;
     const { hash } = window.location;
     if (hash.length === 0) {
     if (hash.length === 0) {
+      console.log('[PAGEVIEW-DEBUG] Auto scroll skipped - no hash');
       return;
       return;
     }
     }
 
 
@@ -136,13 +156,31 @@ export const PageView = (props: Props): JSX.Element => {
     : null;
     : null;
 
 
   const Contents = () => {
   const Contents = () => {
+    const contentsRenderStartTime = performance.now();
+    console.log('[PAGEVIEW-DEBUG] Contents component render started:', {
+      isNotFound,
+      hasPage: page != null,
+      hasRevision: page?.revision != null,
+      pageId: page?._id,
+      timestamp: new Date().toISOString(),
+      contentsRenderStartTime,
+    });
+
     if (isNotFound || page?.revision == null) {
     if (isNotFound || page?.revision == null) {
+      console.log('[PAGEVIEW-DEBUG] Rendering NotFoundPage');
       return <NotFoundPage path={pagePath} />;
       return <NotFoundPage path={pagePath} />;
     }
     }
 
 
     const markdown = page.revision.body;
     const markdown = page.revision.body;
     const rendererOptions = viewOptions ?? generateSSRViewOptions(rendererConfig, pagePath);
     const rendererOptions = viewOptions ?? generateSSRViewOptions(rendererConfig, pagePath);
 
 
+    console.log('[PAGEVIEW-DEBUG] Rendering page content:', {
+      markdownLength: markdown?.length,
+      hasViewOptions: viewOptions != null,
+      isSlide: isSlide != null,
+      renderDuration: performance.now() - contentsRenderStartTime,
+    });
+
     return (
     return (
       <>
       <>
         <PageContentsUtilities />
         <PageContentsUtilities />
@@ -168,6 +206,16 @@ export const PageView = (props: Props): JSX.Element => {
     );
     );
   };
   };
 
 
+  // DEBUG: Log final render completion time
+  const renderEndTime = performance.now();
+  console.log('[PAGEVIEW-DEBUG] PageView render completed:', {
+    pagePath,
+    currentPageId,
+    pageId: page?._id,
+    totalRenderDuration: renderEndTime - renderStartTime,
+    timestamp: new Date().toISOString(),
+  });
+
   return (
   return (
     <PageViewLayout
     <PageViewLayout
       className={className}
       className={className}

+ 42 - 5
apps/app/src/pages/[[...path]]/use-same-route-navigation.ts

@@ -45,7 +45,7 @@ const usePageStateManager = () => {
     });
     });
 
 
     try {
     try {
-      // OPTIMIZATION: Only update pageId if it actually changes
+      // BACK TO ORIGINAL: Only update pageId if it actually changes
       const currentPageId = pageId;
       const currentPageId = pageId;
       if (currentPageId !== targetPageId) {
       if (currentPageId !== targetPageId) {
         console.log('[NAV-DEBUG] Updating pageId:', { from: currentPageId, to: targetPageId });
         console.log('[NAV-DEBUG] Updating pageId:', { from: currentPageId, to: targetPageId });
@@ -56,13 +56,19 @@ const usePageStateManager = () => {
       }
       }
 
 
       // Fetch page data
       // Fetch page data
-      console.log('[NAV-DEBUG] Calling fetchCurrentPage with:', targetPathname);
+      const fetchStartTime = performance.now();
+      console.log('[NAV-DEBUG] Calling fetchCurrentPage with:', targetPathname, 'at', fetchStartTime, 'ms');
       const pageData = await fetchCurrentPage(targetPathname);
       const pageData = await fetchCurrentPage(targetPathname);
+      const fetchEndTime = performance.now();
+      console.log('[NAV-DEBUG] fetchCurrentPage completed in:', fetchEndTime - fetchStartTime, 'ms');
 
 
       // Update editing markdown if we have body content
       // Update editing markdown if we have body content
       if (pageData?.revision?.body !== undefined) {
       if (pageData?.revision?.body !== undefined) {
+        const markdownUpdateStartTime = performance.now();
         console.log('[NAV-DEBUG] Updating editing markdown, body length:', pageData.revision.body.length);
         console.log('[NAV-DEBUG] Updating editing markdown, body length:', pageData.revision.body.length);
         mutateEditingMarkdown(pageData.revision.body);
         mutateEditingMarkdown(pageData.revision.body);
+        const markdownUpdateEndTime = performance.now();
+        console.log('[NAV-DEBUG] Markdown update completed in:', markdownUpdateEndTime - markdownUpdateStartTime, 'ms');
       }
       }
 
 
       console.log('[NAV-DEBUG] Navigation successful for:', targetPathname);
       console.log('[NAV-DEBUG] Navigation successful for:', targetPathname);
@@ -103,10 +109,12 @@ export const useSameRouteNavigation = (props: Props): void => {
 
 
   // Track the last processed pathname to prevent unnecessary operations
   // Track the last processed pathname to prevent unnecessary operations
   const lastProcessedPathnameRef = useRef<string | null>(null);
   const lastProcessedPathnameRef = useRef<string | null>(null);
+  const lastProcessedPageIdRef = useRef<string | null>(null);
   const isFetchingRef = useRef<boolean>(false);
   const isFetchingRef = useRef<boolean>(false);
 
 
   // Process pathname changes - monitor both props.currentPathname and router.asPath
   // Process pathname changes - monitor both props.currentPathname and router.asPath
   useEffect(() => {
   useEffect(() => {
+    const startTime = performance.now();
     console.log('[NAV-DEBUG] useEffect triggered:', {
     console.log('[NAV-DEBUG] useEffect triggered:', {
       targetPathname,
       targetPathname,
       lastProcessedPathname: lastProcessedPathnameRef.current,
       lastProcessedPathname: lastProcessedPathnameRef.current,
@@ -114,6 +122,8 @@ export const useSameRouteNavigation = (props: Props): void => {
       currentPageId: pageId,
       currentPageId: pageId,
       currentPagePath: currentPage?.path,
       currentPagePath: currentPage?.path,
       isFetching: isFetchingRef.current,
       isFetching: isFetchingRef.current,
+      timestamp: new Date().toISOString(),
+      performanceStart: startTime,
     });
     });
 
 
     // Skip if we already processed this pathname
     // Skip if we already processed this pathname
@@ -140,6 +150,26 @@ export const useSameRouteNavigation = (props: Props): void => {
       currentPagePath,
       currentPagePath,
     });
     });
 
 
+    // Enhanced duplicate check: prevent navigation to same page by both pathname and pageId
+    const isSamePathname = lastProcessedPathnameRef.current === targetPathname;
+    const isSamePageId = targetPageId && lastProcessedPageIdRef.current === targetPageId;
+    const isCurrentPageSame = pageId && pageId === targetPageId;
+
+    if (isSamePathname || isSamePageId || isCurrentPageSame) {
+      console.log('[NAV-DEBUG] Skipping - same page detected:', {
+        isSamePathname,
+        isSamePageId,
+        isCurrentPageSame,
+        lastProcessedPathname: lastProcessedPathnameRef.current,
+        lastProcessedPageId: lastProcessedPageIdRef.current,
+        currentPageId: pageId,
+      });
+      // Update tracking refs even when skipping
+      lastProcessedPathnameRef.current = targetPathname;
+      if (targetPageId) lastProcessedPageIdRef.current = targetPageId;
+      return;
+    }
+
     // Use extracted shouldFetchPage function
     // Use extracted shouldFetchPage function
     const shouldFetch = shouldFetchPage({
     const shouldFetch = shouldFetchPage({
       targetPageId,
       targetPageId,
@@ -163,15 +193,22 @@ export const useSameRouteNavigation = (props: Props): void => {
     }
     }
 
 
     isFetchingRef.current = true;
     isFetchingRef.current = true;
-    console.log('[NAV-DEBUG] Starting navigation for:', targetPathname);
+    console.log('[NAV-DEBUG] Starting navigation for:', targetPathname, 'at', performance.now() - startTime, 'ms');
 
 
     const performNavigation = async(): Promise<void> => {
     const performNavigation = async(): Promise<void> => {
+      const navigationStartTime = performance.now();
       await updatePageState(targetPathname, targetPageId);
       await updatePageState(targetPathname, targetPageId);
+      const navigationEndTime = performance.now();
 
 
       // Mark as processed regardless of success to prevent retry loops
       // Mark as processed regardless of success to prevent retry loops
       lastProcessedPathnameRef.current = targetPathname;
       lastProcessedPathnameRef.current = targetPathname;
+      if (targetPageId) lastProcessedPageIdRef.current = targetPageId;
       isFetchingRef.current = false;
       isFetchingRef.current = false;
-      console.log('[NAV-DEBUG] Navigation completed for:', targetPathname);
+      console.log('[NAV-DEBUG] Navigation completed for:', targetPathname, {
+        navigationDuration: navigationEndTime - navigationStartTime,
+        totalDuration: navigationEndTime - startTime,
+        timestamp: new Date().toISOString(),
+      });
     };
     };
 
 
     performNavigation();
     performNavigation();
@@ -180,7 +217,7 @@ export const useSameRouteNavigation = (props: Props): void => {
   }, [
   }, [
     targetPathname, // Memoized value that includes both router.asPath and props.currentPathname
     targetPathname, // Memoized value that includes both router.asPath and props.currentPathname
     hasInitialData, // Memoized value for initial data check
     hasInitialData, // Memoized value for initial data check
-    pageId, // Page ID changes
+    // pageId removed to prevent infinite loops when fetchCurrentPage updates the pageId atom
   ]);
   ]);
 
 
   // Cleanup on unmount
   // Cleanup on unmount

+ 6 - 0
apps/app/src/states/page/use-fetch-current-page.ts

@@ -40,6 +40,7 @@ export const useFetchCurrentPage = (): {
 
 
   const fetchCurrentPage = useAtomCallback(
   const fetchCurrentPage = useAtomCallback(
     useCallback(async(get, set, currentPathname?: string) => {
     useCallback(async(get, set, currentPathname?: string) => {
+      const fetchStartTime = performance.now();
       const currentPath = currentPathname || (isClient() ? decodeURIComponent(window.location.pathname) : '');
       const currentPath = currentPathname || (isClient() ? decodeURIComponent(window.location.pathname) : '');
 
 
       const currentPageId = get(currentPageIdAtom);
       const currentPageId = get(currentPageIdAtom);
@@ -50,6 +51,7 @@ export const useFetchCurrentPage = (): {
         currentPath,
         currentPath,
         currentPageId,
         currentPageId,
         timestamp: new Date().toISOString(),
         timestamp: new Date().toISOString(),
+        performanceStart: fetchStartTime,
         isRootPage: currentPath === '/',
         isRootPage: currentPath === '/',
       });
       });
 
 
@@ -82,10 +84,12 @@ export const useFetchCurrentPage = (): {
           return null; // No valid identifier
           return null; // No valid identifier
         }
         }
 
 
+        const apiStartTime = performance.now();
         const response = await apiv3Get<{ page: IPagePopulatedToShowRevision }>(
         const response = await apiv3Get<{ page: IPagePopulatedToShowRevision }>(
           '/page',
           '/page',
           apiParams,
           apiParams,
         );
         );
+        const apiEndTime = performance.now();
 
 
         const newData = response.data.page;
         const newData = response.data.page;
 
 
@@ -96,6 +100,8 @@ export const useFetchCurrentPage = (): {
           isRootPage: newData?.path === '/',
           isRootPage: newData?.path === '/',
           previousPageId: currentPageId,
           previousPageId: currentPageId,
           pageIdChanged: newData?._id !== currentPageId,
           pageIdChanged: newData?._id !== currentPageId,
+          apiDuration: apiEndTime - apiStartTime,
+          totalDuration: apiEndTime - fetchStartTime,
         });
         });
 
 
         // Batch atom updates to minimize re-renders
         // Batch atom updates to minimize re-renders