Skip to content

Add experimental.cachedNavigations feature flag#90928

Merged
unstubbable merged 1 commit intocanaryfrom
hl/cached-navigations-feature-flag
Mar 6, 2026
Merged

Add experimental.cachedNavigations feature flag#90928
unstubbable merged 1 commit intocanaryfrom
hl/cached-navigations-feature-flag

Conversation

@unstubbable
Copy link
Contributor

@unstubbable unstubbable commented Mar 5, 2026

The recent Cached Navigations feature introduced navigation-level caching into the segment cache, where static and dynamic RSC data from navigations and initial HTML loads is cached so that repeat visits can be served instantly. This feature is currently gated behind cacheComponents, meaning it activates for all projects that enable Cache Components.

This change introduces a new experimental.cachedNavigations flag that independently controls the Cached Navigations behavior. The flag defaults to false so we can investigate potential regressions that the feature might have introduced without affecting the broader Cache Components functionality.

The flag requires cacheComponents to also be enabled and throws a configuration error if cachedNavigations is set without it. On the server, the staged rendering paths in app-render.tsx (both RSC request handling and initial HTML rendering) now check cacheComponents && cachedNavigations before producing staged responses. On the client, process.env.__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS is used alongside process.env.__NEXT_CACHE_COMPONENTS for compile-time dead code elimination in the stream tee (app-index.tsx) and the response processing (fetch-server-response.ts).

The cached navigations test suite enables the flag via next.config.ts, and the Cache Components CI jobs export __NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS=true to maintain test coverage.

@nextjs-bot
Copy link
Collaborator

nextjs-bot commented Mar 5, 2026

Tests Passed

@unstubbable unstubbable force-pushed the hl/cached-navigations-feature-flag branch from 0784983 to 52f2534 Compare March 5, 2026 13:41
@nextjs-bot
Copy link
Collaborator

nextjs-bot commented Mar 5, 2026

Stats from current PR

🔴 1 regression

Metric Canary PR Change Trend
node_modules Size 476 MB 476 MB 🔴 +65.5 kB (+0%) ▁▁▁▁▁
📊 All Metrics
📖 Metrics Glossary

Dev Server Metrics:

  • Listen = TCP port starts accepting connections
  • First Request = HTTP server returns successful response
  • Cold = Fresh build (no cache)
  • Warm = With cached build artifacts

Build Metrics:

  • Fresh = Clean build (no .next directory)
  • Cached = With existing .next directory

Change Thresholds:

  • Time: Changes < 50ms AND < 10%, OR < 2% are insignificant
  • Size: Changes < 1KB AND < 1% are insignificant
  • All other changes are flagged to catch regressions

⚡ Dev Server

Metric Canary PR Change Trend
Cold (Listen) 455ms 456ms ▁▁▁▇▇
Cold (Ready in log) 438ms 438ms ▁▂▂▇▇
Cold (First Request) 1.255s 1.255s ▁▃▃▇▇
Warm (Listen) 456ms 457ms ▁▁▁▇▇
Warm (Ready in log) 442ms 443ms ▁▁▁▆▆
Warm (First Request) 352ms 350ms ▁▁▁▆▆
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 455ms 456ms ▁▅▁▁▁
Cold (Ready in log) 437ms 436ms ▅▇▅▂▆
Cold (First Request) 1.940s 1.927s ▄▆▅▁▅
Warm (Listen) 456ms 456ms ▅▁▅▁▁
Warm (Ready in log) 435ms 436ms ▇▇▇▃▆
Warm (First Request) 1.946s 1.932s ▅▅▅▁▅

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 3.854s 3.874s ▂▁▁▆▆
Cached Build 3.939s 3.885s ▂▁▁▆▆
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 13.934s 13.948s ▃▂▂▁▃
Cached Build 14.099s 14.093s ▄▂▂▁▂
node_modules Size 476 MB 476 MB 🔴 +65.5 kB (+0%) ▁▁▁▁▁
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles: **401 kB** → **401 kB** ✅ -36 B

80 files with content-based hashes (individual files not comparable between builds)

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 767 B 762 B
Total 767 B 762 B ✅ -5 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 450 B 452 B
Total 450 B 452 B ⚠️ +2 B

📦 Webpack

Client

Main Bundles
Canary PR Change
5528-HASH.js gzip 5.54 kB N/A -
6280-HASH.js gzip 59.4 kB N/A -
6335.HASH.js gzip 169 B N/A -
912-HASH.js gzip 4.59 kB N/A -
e8aec2e4-HASH.js gzip 62.6 kB N/A -
framework-HASH.js gzip 59.7 kB 59.7 kB
main-app-HASH.js gzip 256 B 254 B
main-HASH.js gzip 39.1 kB 39.1 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
262-HASH.js gzip N/A 4.59 kB -
2889.HASH.js gzip N/A 169 B -
5602-HASH.js gzip N/A 5.55 kB -
6948ada0-HASH.js gzip N/A 62.6 kB -
9544-HASH.js gzip N/A 60.2 kB -
Total 233 kB 234 kB ⚠️ +738 B
Polyfills
Canary PR Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Total 39.4 kB 39.4 kB
Pages
Canary PR Change
_app-HASH.js gzip 194 B 194 B
_error-HASH.js gzip 183 B 180 B 🟢 3 B (-2%)
css-HASH.js gzip 331 B 330 B
dynamic-HASH.js gzip 1.81 kB 1.81 kB
edge-ssr-HASH.js gzip 256 B 256 B
head-HASH.js gzip 351 B 352 B
hooks-HASH.js gzip 384 B 383 B
image-HASH.js gzip 580 B 581 B
index-HASH.js gzip 260 B 260 B
link-HASH.js gzip 2.51 kB 2.51 kB
routerDirect..HASH.js gzip 320 B 319 B
script-HASH.js gzip 386 B 386 B
withRouter-HASH.js gzip 315 B 315 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Total 7.98 kB 7.98 kB ✅ -1 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 125 kB 125 kB
page.js gzip 254 kB 254 kB
Total 378 kB 379 kB ⚠️ +609 B
Middleware
Canary PR Change
middleware-b..fest.js gzip 617 B 614 B
middleware-r..fest.js gzip 156 B 155 B
middleware.js gzip 43.4 kB 43.6 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 45 kB 45.2 kB ⚠️ +224 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 715 B 718 B
Total 715 B 718 B ⚠️ +3 B
Build Cache
Canary PR Change
0.pack gzip 4.03 MB 4.04 MB 🔴 +9.37 kB (+0%)
index.pack gzip 104 kB 103 kB
index.pack.old gzip 103 kB 103 kB
Total 4.24 MB 4.25 MB ⚠️ +8.96 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 321 kB 321 kB
app-page-exp..prod.js gzip 170 kB 170 kB
app-page-tur...dev.js gzip 321 kB 321 kB
app-page-tur..prod.js gzip 170 kB 170 kB
app-page-tur...dev.js gzip 318 kB 318 kB
app-page-tur..prod.js gzip 168 kB 168 kB
app-page.run...dev.js gzip 318 kB 318 kB
app-page.run..prod.js gzip 168 kB 169 kB
app-route-ex...dev.js gzip 70.3 kB 70.3 kB
app-route-ex..prod.js gzip 48.6 kB 48.6 kB
app-route-tu...dev.js gzip 70.4 kB 70.4 kB
app-route-tu..prod.js gzip 48.7 kB 48.7 kB
app-route-tu...dev.js gzip 69.9 kB 69.9 kB
app-route-tu..prod.js gzip 48.4 kB 48.4 kB
app-route.ru...dev.js gzip 69.9 kB 69.9 kB
app-route.ru..prod.js gzip 48.4 kB 48.4 kB
dist_client_...dev.js gzip 324 B 324 B
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
dist_client_...dev.js gzip 317 B 317 B
pages-api-tu...dev.js gzip 43.2 kB 43.2 kB
pages-api-tu..prod.js gzip 32.9 kB 32.9 kB
pages-api.ru...dev.js gzip 43.2 kB 43.2 kB
pages-api.ru..prod.js gzip 32.9 kB 32.9 kB
pages-turbo....dev.js gzip 52.6 kB 52.6 kB
pages-turbo...prod.js gzip 38.5 kB 38.5 kB
pages.runtim...dev.js gzip 52.6 kB 52.6 kB
pages.runtim..prod.js gzip 38.5 kB 38.5 kB
server.runti..prod.js gzip 61.8 kB 61.8 kB
Total 2.83 MB 2.83 MB ⚠️ +943 B
📝 Changed Files (9 files)

Files with changes:

  • app-page-exp..ntime.dev.js
  • app-page-exp..time.prod.js
  • app-page-tur..ntime.dev.js
  • app-page-tur..time.prod.js
  • app-page-tur..ntime.dev.js
  • app-page-tur..time.prod.js
  • app-page.runtime.dev.js
  • app-page.runtime.prod.js
  • server.runtime.prod.js
View diffs
app-page-exp..ntime.dev.js
failed to diff
app-page-exp..time.prod.js
failed to diff
app-page-tur..ntime.dev.js
failed to diff
app-page-tur..time.prod.js

Diff too large to display

app-page-tur..ntime.dev.js
failed to diff
app-page-tur..time.prod.js

Diff too large to display

app-page.runtime.dev.js
failed to diff
app-page.runtime.prod.js
failed to diff
server.runtime.prod.js

Diff too large to display

📎 Tarball URL
https://vercel-packages.vercel.app/next/commits/8f43e94a6f3a94447e0a326145efed0ac8e06c52/next

@unstubbable unstubbable force-pushed the hl/cached-navigations-feature-flag branch from 52f2534 to f696947 Compare March 5, 2026 14:15
@unstubbable unstubbable force-pushed the hl/cached-navigations-feature-flag branch 4 times, most recently from eafb189 to 97f89aa Compare March 5, 2026 16:32
@unstubbable unstubbable force-pushed the hl/cached-navigations-feature-flag branch 2 times, most recently from ce794f8 to 0325883 Compare March 5, 2026 18:06
@unstubbable unstubbable marked this pull request as ready for review March 5, 2026 18:07
@vercel
Copy link
Contributor

vercel bot commented Mar 5, 2026

Notifying the following users due to files changed in this PR based on this repo's notify modifiers:

@timneutkens, @ijjk, @shuding, @huozhi:

packages/next/src/server/config.ts

@unstubbable unstubbable enabled auto-merge (squash) March 5, 2026 18:07
@unstubbable unstubbable disabled auto-merge March 5, 2026 18:15
@unstubbable unstubbable force-pushed the hl/cached-navigations-feature-flag branch from 0325883 to 8f43e94 Compare March 5, 2026 18:26
The recent Cached Navigations feature introduced navigation-level
caching into the segment cache, where static and dynamic RSC data from
navigations and initial HTML loads is cached so that repeat visits can
be served instantly. This feature is currently gated behind
`cacheComponents`, meaning it activates for all projects that enable
Cache Components.

This change introduces a new `experimental.cachedNavigations` flag that
independently controls the Cached Navigations behavior. The flag
defaults to `false` so we can investigate potential regressions that the
feature might have introduced without affecting the broader Cache
Components functionality.

The flag requires `cacheComponents` to also be enabled and throws a
configuration error if `cachedNavigations` is set without it. On the
server, the staged rendering paths in `app-render.tsx` (both RSC request
handling and initial HTML rendering) now check `cacheComponents &&
cachedNavigations` before producing staged responses. On the client,
`process.env.__NEXT_CACHED_NAVIGATIONS` is used alongside
`process.env.__NEXT_CACHE_COMPONENTS` for compile-time dead code
elimination in the stream tee (`app-index.tsx`) and the response
processing (`fetch-server-response.ts`).

The cached navigations test suite enables the flag via `next.config.ts`,
and the Cache Components CI jobs export `__NEXT_CACHED_NAVIGATIONS=true`
to maintain test coverage.
@unstubbable unstubbable force-pushed the hl/cached-navigations-feature-flag branch from 8f43e94 to cc6d3ba Compare March 6, 2026 07:38
@unstubbable unstubbable merged commit d08f4dc into canary Mar 6, 2026
541 of 548 checks passed
@unstubbable unstubbable deleted the hl/cached-navigations-feature-flag branch March 6, 2026 09:39
sokra pushed a commit that referenced this pull request Mar 6, 2026
The recent Cached Navigations feature introduced navigation-level
caching into the segment cache, where static and dynamic RSC data from
navigations and initial HTML loads is cached so that repeat visits can
be served instantly. This feature is currently gated behind
`cacheComponents`, meaning it activates for all projects that enable
Cache Components.

This change introduces a new `experimental.cachedNavigations` flag that
independently controls the Cached Navigations behavior. The flag
defaults to `false` so we can investigate potential regressions that the
feature might have introduced without affecting the broader Cache
Components functionality.

The flag requires `cacheComponents` to also be enabled and throws a
configuration error if `cachedNavigations` is set without it. On the
server, the staged rendering paths in `app-render.tsx` (both RSC request
handling and initial HTML rendering) now check `cacheComponents &&
cachedNavigations` before producing staged responses. On the client,
`process.env.__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS` is used alongside
`process.env.__NEXT_CACHE_COMPONENTS` for compile-time dead code
elimination in the stream tee (`app-index.tsx`) and the response
processing (`fetch-server-response.ts`).

The cached navigations test suite enables the flag via `next.config.ts`,
and the Cache Components CI jobs export
`__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS=true` to maintain test coverage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants