[NEXT-1187] Link navigation with loading.tsx is not instant for dynamic pages
Problem
Verify canary release - [X] I verified that the issue exists in the latest Next.js canary release Provide environment information Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 22.1.0: Sun Oct 9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103 Binaries: Node: 18.12.1 npm: 8.19.2 Yarn: 1.22.19 pnpm: N/A Relevant packages: next: 13.0.6-canary.2 eslint-config-next: 13.0.5 react: 18.2.0 react-dom: 18.2.0 Which area of Next.js is affected? (leave empty if unsure) App directory (appDir: true), Routing (next/router, next/navigation, next/link) Link to reproduction - Issues with a link to complete (but minimal) reproduction code will be addressed faster https://github.com/tonypizzicato/next-13-loading To Reproduce - pull the repo - run `yarn install && yarn dev` - open `localhost:3000` in the browser - go to the "Careers" page - reload the page - set some throttling in devtools - click different pages in the menu - notice that "Careers" page loading state and route change are done instantly but with some delay for other pages Describe the Bug When you have a dynamic page with `loading.tsx` the route change and showing the loading animation are instant only for the page, which was freshly loaded. For other dynamic pages it hits the server first, then shows the loading state <img width="193" alt="Screenshot 2022-11-29 at 23 19 38" src="https://user-images.
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Optimize Loading State for Dynamic Pages in Next.js
The delay in loading state for dynamic pages is caused by Next.js fetching data from the server before transitioning to the new route. This is particularly noticeable when navigating away from a page that has already been loaded, as the loading state is only triggered after the server response is received.
Awaiting Verification
Be the first to verify this fix
- 1
Implement Client-Side Data Fetching
Modify the dynamic pages to use client-side data fetching methods such as SWR or React Query. This allows the application to fetch data on the client side, reducing the perceived loading time during navigation.
typescriptimport useSWR from 'swr'; const fetcher = (url) => fetch(url).then((res) => res.json()); function CareersPage() { const { data, error } = useSWR('/api/careers', fetcher); if (error) return <div>Failed to load</div>; if (!data) return <div>Loading...</div>; return <div>{data.title}</div>; } - 2
Utilize Next.js Prefetching
Ensure that links to dynamic pages are prefetching their data. This can be done using the `next/link` component with the `prefetch` prop set to true, which will load the data in the background when the link is visible.
typescript<Link href="/careers" prefetch>Careers</Link> - 3
Adjust Loading State Logic
Modify the loading state logic in `loading.tsx` to show a loading indicator immediately when a link is clicked, rather than waiting for the server response. This can improve the perceived speed of navigation.
typescriptconst Loading = () => { useEffect(() => { // Trigger loading state immediately setLoading(true); }, []); return <div>Loading...</div>; }; - 4
Test with Throttling
After implementing the above changes, test the application with network throttling enabled in the browser's developer tools to ensure that the loading state behaves as expected across all dynamic pages.
N/AN/A
Validation
Confirm that navigating between dynamic pages shows the loading state immediately without noticeable delays, even under throttled network conditions. Additionally, check that data is being fetched correctly on the client side without impacting server performance.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep