Skip to content

Commit

Permalink
skip seeding prefetch cache in development (#72191)
Browse files Browse the repository at this point in the history
Since prefetching is disabled in development, seeding the prefetch cache
for the initially rendered page can lead to an inconsistent navigation
experience, where the initially visited page won't behave the same as
subsequent pages that you navigate to.

We should ultimately get to a place where the prefetch behavior is
consistent between dev/start to keep the production behavior as
consistent as possible with the development experience, but when we do
so, we would want to enable it across the board.

This happens to fix a bug with dynamicIO because the server-patch action
(which happens when data is missing for a rendered segment) was
mismatching the router state tree, which triggers a hard navigation to
recover. This happens to fix the issue because the router never hits the
server patch case, which is when the hard navigation could occur.
Separately, we're working to verify why the seeded prefetch entry might
have caused this change in behavior only in dev.

Note: this modifies a navigation test that was asserting on RSC requests
taking place, which will now happen in dev as there'll be no prefetch
entry.

Fixes #72150
  • Loading branch information
ztanner authored Nov 1, 2024
1 parent e8421c5 commit a7610a6
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,13 @@ export function createInitialRouterState({
null,
}

if (location) {
if (process.env.NODE_ENV !== 'development' && location) {
// Seed the prefetch cache with this page's data.
// This is to prevent needlessly re-prefetching a page that is already reusable,
// and will avoid triggering a loading state/data fetch stall when navigating back to the page.
// We don't currently do this in development because links aren't prefetched in development
// so having a mismatch between prefetch/no prefetch provides inconsistent behavior based on which page
// was loaded first.
const url = new URL(
`${location.pathname}${location.search}`,
location.origin
Expand Down
11 changes: 8 additions & 3 deletions test/e2e/app-dir/navigation/navigation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,17 @@ describe('app dir - navigation', () => {
await checkLink('top', 0)
await checkLink('non-existent', 0)

// there should have been no RSC calls to fetch data
expect(hasRscRequest).toBe(false)
if (!isNextDev) {
// there should have been no RSC calls to fetch data
// this is skipped in development because there'll never be a prefetch cache
// entry for the loaded page and so every request will be a cache miss.
expect(hasRscRequest).toBe(false)
}

// There should be an RSC request if the query param is changed
await checkLink('query-param', 2284)
await browser.waitForIdleNetwork()

// There should be an RSC request if the query param is changed
expect(hasRscRequest).toBe(true)
})

Expand Down

0 comments on commit a7610a6

Please sign in to comment.