-
Notifications
You must be signed in to change notification settings - Fork 26.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parallel Routes cause redundant RSC fetches on navigation #65878
Comments
@ztanner , tagging you in the hopes that I've misconfigured something in a way that will be easy for you to spot 🙏. This one is kind of a big deal for us because I believe it's increasing our server costs significantly (since we're paying to do the same work many times when a user navigates to a page). |
Do you do any api fetch requests on the server side? |
Hi @steve-marmalade -- Thanks for the great repro and description, as always 😄 As a quick workaround for the issue you're describing here, there're a few options:
Now, for an explanation of why it's happening: prefetch requests will return RSC data up to the nearest loading boundary. This is so that a prefetch doesn't lead to overfetching data, especially if you're linking to a page that has an expensive subtree. When a route is prefetched, the idea is that clicking the link will immediately show the prefetched loading boundary, while the part that suspended is streamed in. In this case, since there's a loading.tsx in the I think I see a way to optimize this, and will work on a PR this coming week. Thanks for the heads up! |
Thank you for the detailed description and the workaround (which does seem to alleviate the problem!) Just want to clarify one thing for my own understanding:
Even in this case where the router triggers a data fetch for each slot, I still wouldn't expect those requests to take ~1 second each in my demo, because most of the slots are just returning |
Right now data is fetched per-page, rather than having the ability to more granularly fetch per-segment/slot. This is something we're planning to address soon so that the Next.js server can be smarter about only requesting the data it needs, rather than returning more data than necessary. At the moment, when the router sees missing data for the |
Heya @ztanner , I know there's a ton going on -- any chance this fix makes it into Canary this week? |
Hey @steve-marmalade -- I talked with some folks on the team and the concern is that, while many people use I'll need to think through if there's an alternate approach we could do here, which may take a little bit more time. 🙏 |
Got it, thanks for the update. Relatedly: would you expect that scrolling to an |
Hey @ztanner, this been hanging for a while, can you please check it out again? I doubt that parallel routes are actually usable in NextJS unless this is fixed. And unfortunately for me, I nested lots of parallel routes with |
I've debugged the issue (as much as I could), and was able to resolve it. TLDR: I refactored my top-level parallel slots that were rendered on a client (via Next.js.Debug.mp4my dumpy dump file: https://gist.github.com/dalechyn/43da78d2dbdd1efc3c46fb4d1f04a91c UPDATE: That didn't help. I now need to migrate from using any Suspense-throwing calls as this bug seriously affects production. UPDATE: Migrating to imperative load handling didn't help too. But it sped up the website though. Still getting lots of requests. UPDATE: Removing parallel slots by renaming them ( Most of my components are client-side, and most of the pages. The amount of overload that is currently added and maintained is crazy. By doing this "optimization" (a.k.a "deparallelization" :) ), the amount of requests from switching to the root page and another one and vice versa was reduced from |
Link to the code that reproduces this issue
https://github.com/marmalade-labs/parallel-route-rerender
To Reproduce
bun run build && bun start
) or navigate to https://parallel-route-rerender.vercel.app/aCurrent vs. Expected behavior
Current Behavior
If you open the Network tab in DevTools, when you click a card you will see 21 fetches for the current route (with different
?_rsc=
params), which I believe correspond to the 21 different parallel slots in the layout.Maybe this is intended in the sense that each request might correspond to a specific slot. However, each request appears to be re-running the matched slots (which will always and only be
/app/[letter]/page.tsx
and/app/[letter]/@grid/page.tsx
). I demonstrate by adding a 1 second sleep in those pages, but not in any others (which should just be rendering a no-opdefault.tsx
), and yet we can see that each of the 21 requests takes > 1 second.Expected Behavior
Whether or not we expect 21 different HTTP requests, I would only expect that each slot is rendered once. So we should either see 1 request that takes ~ 1 second, or 21 requests where 2 of them take 1 second and the rest are <100 ms.
Provide environment information
Operating System: Platform: linux Arch: x64 Version: #1 SMP PREEMPT_DYNAMIC Tue, 07 May 2024 21:35:54 +0000 Available memory (MB): 31886 Available CPU cores: 8 Binaries: Node: 18.20.2 npm: 10.8.0 Yarn: 1.22.22 pnpm: 8.15.5 Relevant Packages: next: 14.3.0-canary.68 // Latest available version is detected (14.3.0-canary.68). eslint-config-next: 14.2.3 react: 18.3.1 react-dom: 18.3.1 typescript: 5.4.5 Next.js Config: output: N/A
Which area(s) are affected? (Select all that apply)
Navigation, Parallel & Intercepting Routes
Which stage(s) are affected? (Select all that apply)
next start (local), Vercel (Deployed)
Additional context
No response
The text was updated successfully, but these errors were encountered: