Skip to content
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

backport: style loading and navigation fixes #69458

Closed

Conversation

Copy link
Contributor

github-actions bot commented Aug 29, 2024

Hi there 👋

It looks like this PR introduces broken links to the docs, please take a moment to fix them before merging:

Broken link Type File
/docs/app/building-your-application/optimizing/package-bundling#analyzing-javascript-bundles link /docs/02-app/01-building-your-application/06-optimizing/13-memory-usage.mdx

Thank you 🙏

@lubieowoce lubieowoce changed the title add layerAssets property to FlightDataPath (#66354) backport: style loading and navigation fixes Aug 29, 2024
@lubieowoce lubieowoce force-pushed the backport-14-3-0/parallel-stylesheets-and-navigations branch 2 times, most recently from 66f1f1d to 994cad2 Compare August 29, 2024 16:57
@ijjk
Copy link
Member

ijjk commented Aug 29, 2024

Failing test suites

Commit: 6d33095

TURBOPACK=1 pnpm test-start test/e2e/prerender.test.ts (turbopack)

  • Prerender > should on-demand revalidate for fallback: blocking with onlyGenerated if generated
Expand output

● Prerender › should on-demand revalidate for fallback: blocking with onlyGenerated if generated

expect(received).toMatch(expected)

Expected pattern: /(HIT|STALE)/
Received string:  "MISS"

  2296 |
  2297 |         expect(initialTime).toBe($2('#time').text())
> 2298 |         expect(res2.headers.get('x-nextjs-cache')).toMatch(/(HIT|STALE)/)
       |                                                    ^
  2299 |
  2300 |         const res3 = await fetchViaHTTP(
  2301 |           next.url,

  at Object.toMatch (e2e/prerender.test.ts:2298:52)

Read more about building and testing Next.js in contributing.md.

pnpm test-dev test/development/middleware-errors/index.test.ts

  • middleware - development errors > when there is a compilation error after boot > logs the error correctly
Expand output

● middleware - development errors › when there is a compilation error after boot › logs the error correctly

TIMED OUT: success

undefined

Error: expect(received).toEqual(expected) // deep equality

Expected: 2
Received: 3

  651 |
  652 |   if (hardError) {
> 653 |     throw new Error('TIMED OUT: ' + regex + '\n\n' + content + '\n\n' + lastErr)
      |           ^
  654 |   }
  655 |   return false
  656 | }

  at check (lib/next-test-utils.ts:653:11)
  at Object.<anonymous> (development/middleware-errors/index.test.ts:291:9)

Read more about building and testing Next.js in contributing.md.

@lubieowoce
Copy link
Member Author

hmmm. i can reliably reproduce the failure in pnpm test-dev test/e2e/app-dir/navigation/navigation.test.ts, i guess we need to fix that?

(can't reproduce __NEXT_EXPERIMENTAL_PPR=true pnpm test-dev test/e2e/app-dir/actions-navigation/index.test.ts, so possibly a flake)

@lubieowoce lubieowoce force-pushed the backport-14-3-0/parallel-stylesheets-and-navigations branch from d79b5fe to 0c34729 Compare August 30, 2024 14:44
// https://github.com/facebook/react/pull/28951
// but the backport branch is still on older react
// waitForNEffects: 1,
waitForNEffects: isNextDev ? 2 : 1,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ztanner i adjusted this because __NEXT_EXPERIMENTAL_PPR=true still gave me a 2 here. any idea why this'd change here? that's a bit suspicious

When the router encounters a `stale` cache entry, it clears the `rsc`
data so that it can be fetched in render. All navigations (even just for
hash fragments) flow through the navigation reducer, which has logic to
discard any existing cache entries when the cache is stale.

This bug has become more obvious after removing the default 30s cache,
which would previously have masked it.

This updates the existing handling that clears flight data to not do so
if only the hash changes as there would be no server changes in this
case.

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

- Run `pnpm prettier-fix` to fix formatting issues before opening the
PR.
- Read the Docs Contribution Guide to ensure your contribution follows
the docs guidelines:
https://nextjs.org/docs/community/contribution-guide

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

Closes NEXT-
Fixes #

-->
This adds a new `layerAssets` property (containing styles and script
tags) to `FlightDataPath`. Previously these were lumped in with the
`head` node, but we intentionally only ever render a single `head`, to
avoid duplicating metadata. This would mean `<AppRouter />` would only
ever render imported stylesheets for a single page in a racey way.
However, since Float handles hoisting and deduping these style tags,
we're safe to render them for each segment.

This PR introduces no change in behavior, aside from sending
`layerAssets` down from the server and storing it in the client router
cache. These nodes aren't rendered -- this is done in #66300.
This takes the `layerAssets` property from the previous PR and actually
renders it, replacing the previous style handling. This ensures that
when multiple page segments are rendered on screen, all of their
associated CSS files are loaded. The existing `findHeadInCache` method
only ever returns a single head node, which means it’d miss stylesheets.

Fixes #59308
Fixes #63465
This removes the `lazyDataResolved` property on the CacheNode -- it was
added to avoid repeatedly applying the server-patch action while data is
missing (and while waiting for the server to respond), but if we just
move the patch action be attached to then server fetch, there's no need
to separate these (we're already suspending indefinitely while data is
missing)
…67435)

This PR was originally intended to ensure style/script tags were always
rendered for all visible parallel routes, as before only the "first"
child was rendered, similar to `head`.

However, it caused a regression in PPR navigations, as the pending task
on the `layerAssets` CacheNode meant that the `useDeferredValue` call in
`layout-router` wouldn't be able to immediately switch to the prefetched
RSC payload, as it was blocked by the dynamic response.

Since `rsc` and `layerAssets` are both created by the same thing, this
stack of PRs rewinds some of that work to combine them.

This PR only reverts the previous implementation, and adds a test for
the PPR navigation case that was failing.

**Note: While I've split these PRs out for readability, this should land
with #67436 as this PR by itself does not restore the CSS behavior that
was fixed in the original implementation.**
During SSR, we walk the component tree and pass and immediately seed the
router cache with the tree.

We also seed the prefetch cache for the initial route with the same tree
data because navigations events will apply the data from the prefetch
cache. The rationale for this is that since we already have the data, we
might as well seed it in the prefetch cache, to save a server round trip
later.

The way we're seeding the cache introduced a bug when PPR is turned on:
PPR expects that each element in `FlightDataPath` is of length 3,
corresponding with: `[PrefetchedTree, SeedData, Head]`. However, we were
seeding it with 4 items: `[Segment, PrefetchedTree, SeedData, Head]`.
When the forked router implementation sees anything other than 3 items,
it reverts back to the pre-PPR behavior, which means the data will be
lazy-fetched during render rather than eagerly in the reducer.

As a result, when navigating back to the page that was seeded during
SSR, it wouldn't immediately apply the static parts to the UI: it'd
block until the dynamic render finished.

This PR also includes a small change to ensure reused tasks don’t
trigger a dynamic request. A navigation test was failing because this PR
fixed a bug that was causing it to hit the non-PPR behavior, which
already handles this correctly.

I've added an explicit test for this in PPR. I've also excluded all of
the `client-cache` tests from PPR, as many of them were already failing
and aren't relevant to PPR, since PPR doesn't currently make use of the
`staleTime`/ cache heuristics that the regular router does.
@lubieowoce lubieowoce force-pushed the backport-14-3-0/parallel-stylesheets-and-navigations branch from 0c34729 to 6d33095 Compare August 30, 2024 15:08
@ztanner
Copy link
Member

ztanner commented Aug 30, 2024

Isolated these changes to just the relevant fix in:

@ztanner ztanner closed this Aug 30, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants