Andrew ClarkandGitHub 64328fe985 Track vary params during static prerendering (#89267)
During prerendering, track which route params each segment accesses.
Params that are NOT accessed can be omitted from the client router's
cache key for that segment, allowing it to be shared across multiple
pages and reducing the number of prefetch requests.

For example, if a page at /shop/[category]/[itemId] only accesses
`category` but not `itemId`, navigating between /shop/electronics/phone
and /shop/electronics/tablet can reuse the same cached page segment,
since only `category` affects its output.

Most of the client-side changes were already implemented in previous
PRs; the core mechanism was already being used for omitting search
params from the cache keys of static segments. This generalizes the
mechanism for all params. So this PR is primarily about adding per-param
tracking on the server and wiring up the logic to send the params to the
client.

Each segment's CacheNodeSeedData contains its own VaryParamsThenable
that resolves to a Set<string> of accessed param names. The thenable is
a mutable tracker during render that accumulates param accesses, then
resolves when rendering completes. The response also includes an `h`
field for head vary params, which tracks params accessed by
generateMetadata/generateViewport separately from segment body access.

The trickiest part of this implementation is the timing. The vary params
thenables represent metadata about the response, but they're also part
of the response itself - they're streamed alongside the segment data. We
can't know which params were accessed until rendering completes, but we
need to resolve all thenables before aborting the stream, or else the
client would block waiting for data that will never arrive.

We address this on both sides. On the server, we resolve all thenables
immediately before aborting. On the client, we read vary params
synchronously using a React Flight optimization: calling
thenable.then(noop) forces Flight to transition from 'resolved_model' to
'fulfilled' without scheduling a microtask. If the thenable still isn't
fulfilled after this, we fall back to null (unknown) rather than
blocking. This ensures the client never suspends on these thenables,
providing a safe fallback if something goes wrong with server timing.

A key distinction is null vs empty Set. An empty Set means the segment
accesses no params and can be shared across all param values - this is
the case for client components (when Cache Components is enabled),
segments without user code, etc. A null value means tracking failed -
either because it's not wired up yet (like runtime prefetches), or due
to some edge case where the thenables weren't resolved in time.

For segments where we know upfront that no params will be accessed, we
use a singleton emptyVaryParamsTracker that's already resolved. This
ensures these segments resolve correctly even if other tracking fails.

In the future, we'll likely optimize the response format by sending a
bitmask instead of a Set of param names. But this is mostly just an
optimization — sending the Set doesn't expose anything new since the
param names are already embedded in the route tree (although that's also
something we could obfuscate in the future).

This does not yet implement vary param tracking during runtime
prefetches - the abort timing needs additional coordination. Deferred to
a separate PR.
2026-01-30 09:48:32 -05:00
2025-10-13 10:43:51 +02:00
2024-10-29 13:06:18 -07:00
2024-06-28 04:41:35 -07:00
2026-01-29 23:07:40 +00:00
2025-01-02 14:31:08 -08:00
2026-01-29 23:07:40 +00:00
2018-10-01 01:02:10 +02:00
2024-08-14 13:05:42 +00:00

Next.js logo

Next.js

Vercel logo NPM version License Join the community on GitHub

Getting Started

Used by some of the world's largest companies, Next.js enables you to create full-stack web applications by extending the latest React features, and integrating powerful Rust-based JavaScript tooling for the fastest builds.

Documentation

Visit https://nextjs.org/docs to view the full documentation.

Community

The Next.js community can be found on GitHub Discussions where you can ask questions, voice ideas, and share your projects with other people.

To chat with other community members you can join the Next.js Discord server.

Do note that our Code of Conduct applies to all Next.js community channels. Users are highly encouraged to read and adhere to it to avoid repercussions.

Contributing

Contributions to Next.js are welcome and highly appreciated. However, before you jump right into it, we would like you to review our Contribution Guidelines to make sure you have a smooth experience contributing to Next.js.

Good First Issues:

We have a list of good first issues that contain bugs that have a relatively limited scope. This is a great place for newcomers and beginners alike to get started, gain experience, and get familiar with our contribution process.


Security

If you believe you have found a security vulnerability in Next.js, we encourage you to responsibly disclose this and NOT open a public issue.

To participate in our Open Source Software Bug Bounty program, please email [email protected]. We will add you to the program and provide further instructions for submitting your report.

S
Description
The React Framework
Readme
2.4 GiB
Languages
JavaScript 55.6%
TypeScript 30%
Rust 12.9%
MDX 0.7%
CSS 0.7%