Commit Graph

1925 Commits

Author SHA1 Message Date
Alexander Lichter e7225b92cc fix(benchmarks): measure eager RSC entry closure (#2208) 2026-06-20 14:43:49 +01:00
Divanshu Chauhan 32973e9ddf fix(rsc): only short-circuit well-known signal digests so real errors reach onRequestError (#2066)
createRscOnErrorHandler treated ANY error carrying a digest field as a
control-flow signal: it returned String(error.digest) and skipped
reportRequestError, so a genuine server-render error that merely carried a
digest (e.g. a hashed digest from sanitizeErrorForClient, or one transported
from a nested boundary) was silently swallowed with no instrumentation and
its digest shipped to the client as if it were a signal.

Mirror Next.js getDigestForWellKnownError: add a helper that recognizes only
genuine signals (redirect / notFound+http-fallback / bailout-to-CSR /
dynamic-server) and gate the short-circuit on it. Non-signal digest errors now
fall through to reportRequestError and keep their existing digest as-is.

Fix the same conflation in createAppPageRscErrorTracker.onRenderError, which
routed any digest-bearing error to the special 307/404-swap slot; gate it on
isNavigationSignalError so real errors reach the error boundary and a later
real signal can still win the slot.

Closes #1978
2026-06-20 14:43:17 +01:00
Nathan Nguyen 46b8fe8ccd perf(server): skip duplicate App RSC vary merge (#2177)
App Router page responses commonly already carry the internal RSC Vary header before response finalization runs. Re-running the generic Vary merge in that case splits and deduplicates the known header value on every SSR response without changing the result.

Read the current Vary value first, set the internal header directly when missing, and only fall back to the generic merge path for custom Vary values that still need preservation and deduplication.
2026-06-20 14:29:46 +01:00
Nathan Nguyen 3e83ab24b4 perf(server): reuse App SSR bfcache metadata (#2182)
* perf(server): reuse App SSR bfcache metadata

* refactor(server): clarify bfcache segment parsing
2026-06-20 14:17:07 +01:00
Alexander Lichter 7c5f4c592a perf(app): omit unused server action runtime (#2206) 2026-06-20 13:51:01 +01:00
Alexander Lichter ef2e4a95dc perf(client): preserve additional route-owned shims (#2205) 2026-06-20 13:38:18 +01:00
Alexander Lichter 4fa904e10e test(e2e): stabilize app router history navigation (#2207)
* test(e2e): stabilize app router history navigation

* test(e2e): isolate temporary Vite caches
2026-06-20 13:37:21 +01:00
Alexander Lichter 94eb44ef66 feat(benchmarks): track eager client entry size (#2190) 2026-06-20 01:37:30 +01:00
James Anderson 3a9fe9927c fix(perf): keep main benchmark runs queued (#2204)
Co-authored-by: James <jamesanderson@cloudflare.com>
2026-06-20 00:36:27 +00:00
Alexander Lichter 85d49ec814 perf(dev): externalize SSR React runtime (#2191)
* perf(dev): externalize SSR React runtime

* fix(test): pass Vite config environment
2026-06-20 01:33:33 +01:00
Alexander Lichter 8da718ba43 perf(app-router): isolate action request detection (#2188) 2026-06-20 01:30:19 +01:00
dependabot[bot] ab6344d391 chore(deps): bump actions/checkout from 6.0.3 to 7.0.0 (#2192)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6.0.3...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 01:29:34 +01:00
Alexander Lichter b9653e8a3a perf(app): omit unused metadata route runtime (#2196)
* perf(app): omit unused metadata route runtime

* fix(app): keep metadata route helper type private

---------

Co-authored-by: James <jamesanderson@cloudflare.com>
2026-06-20 01:26:28 +01:00
Alexander Lichter 6e35d4e206 perf(client): preserve App Router route chunk boundaries (#2189) 2026-06-20 01:25:30 +01:00
Alexander Lichter 9970430c29 perf(app): omit unused middleware runtime (#2194) 2026-06-20 01:15:33 +01:00
Jerry Zhao cd328835da perf(og): use MagicString positional overwrites instead of repeated replaceAll (#2202) 2026-06-20 01:08:50 +01:00
Jerry Zhao 727c0709e5 perf(dev-server): memoize the Pages SSR handler across dev requests (#2201) 2026-06-20 01:08:22 +01:00
Jerry Zhao 680cbafabc perf(mdx): gate the MDX transform handler behind a native id filter (#2200) 2026-06-20 01:05:02 +01:00
Jerry Zhao 31167d8256 refactor(build): drop unreachable fsRoute lookup in prerenderPages (#2195) 2026-06-20 01:04:43 +01:00
Jerry Zhao d69c3cdba6 refactor(plugin): build removeConsole exclude set only after the bail-out checks (#2199) 2026-06-20 01:02:11 +01:00
Jerry Zhao e31398679a refactor(plugin): iterate SERVER_EXPORTS set instead of spreading to an array (#2198) 2026-06-20 01:01:41 +01:00
Jerry Zhao ef31ecff23 refactor(build): drop redundant Array.isArray check in prerenderApp (#2197) 2026-06-20 01:00:51 +01:00
Jerry Zhao 3dc2d83306 refactor(rsc): remove redundant replace in use cache variant parsing (#2193) 2026-06-20 00:56:54 +01:00
Alexander Lichter 92e4df5e33 fix(web): prevent benchmark chart label overlap (#2187) 2026-06-19 16:55:16 +01:00
github-actions[bot] 948a0d9d72 chore: version packages (#2147)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
vinext@0.1.6
2026-06-19 16:53:06 +01:00
James Anderson 656a381de9 fix(og): constrain inlined assets to trusted roots (#2172)
* fix(og): constrain inlined assets to trusted roots

* fix(og): canonicalize asset package boundaries

* test(og): cover canonical boundary intersections

* fix(og): support file-symlinked dependency modules

* docs(og): clarify logical asset boundary resolution

* fix(og): pin symlinked modules to matching packages

* fix(og): keep linked package boundaries narrow

* fix(og): reject workspace-root asset boundaries

* fix(og): name-pin external package boundaries

* fix(og): validate linked package ownership

* fix(og): track linked package ownership

* fix(og): harden linked package provenance

* fix(og): confine captured alias packages

* fix(og): pin captured directory aliases

* fix(og): require alias package ownership

* fix(og): support single-segment aliases

* perf(og): preserve alias lookup precedence

* refactor(og): extract asset ownership policy

* test(og): cover linked package fonts in e2e

* fix(og): recognize resolved package aliases

* fix(og): support regex package aliases

* test(og): isolate linked font fixture

* docs(test): clarify linked font coverage
2026-06-19 16:08:46 +01:00
Alexander Lichter 5581c506b3 feat(web): link benchmark chart points to commits (#2185) 2026-06-19 16:07:51 +01:00
Alexander Lichter 175662f108 feat(web): link benchmark references to GitHub (#2184) 2026-06-19 16:01:49 +01:00
James Anderson a3f137802b fix(perf): avoid dispatch publisher main race (#2180) 2026-06-19 15:22:49 +01:00
James Anderson 0fb4fe475a feat(web): show one hundred benchmark runs (#2178) 2026-06-19 15:04:09 +01:00
Nathan Nguyen 301418a3f1 perf(app-router): defer layout, template and boundary modules to first request (#2145)
* perf(app-router): defer layout, template and boundary modules to first request

The generated RSC entry statically imported every route's layout, template,
loading/error/not-found/forbidden/unauthorized boundary and parallel-slot
module at the top level. On a cold isolate — and on the dev server's first
request — that eagerly evaluated the whole app's segment tree, including
routes never visited in that lifetime. Page and route-handler modules were
already lazy; the surrounding segment modules were not.

Emit those modules as lazy `() => import()` loaders paired with `null`
placeholders in the manifest, and hydrate them onto the route's synchronous
fields in `ensureAppRouteModulesLoaded` before any read (extended from
page/handler to layouts, templates, boundaries and parallel-slot modules).
Intercept layouts hydrate via the dedicated `loadAppInterceptLayouts` because
they live on the match object, not the route. Every reader already runs behind
`ensureAppRouteModulesLoaded` (handler dispatch and `buildPageElements`) or the
intercept resolvers, so no synchronous module field is read before hydration.

The shared intercept `interceptLayouts` arrays keep their `readonly` public
types; the loader is their sole writer and fills slots through one
boundary-local cast, so route metadata stays immutable to callers.

Dev cold start is unchanged on page-heavy apps — pages were already lazy — but
on a boundary-heavy app (80 independent sections, each with
layout+template+error+loading+not-found) first-request module compile drops
704ms -> 534ms (~24%) and time-to-first-200 1917ms -> 1665ms. The saving scales
with the number of unrelated segments deferred.

* test(app-router): localize react max header font fixture

* fix(app-router): dedupe lazy intercept module loads

* fix(app-router): share intercept load state across matches

* docs(app-router): explain root layout loader reuse

---------

Co-authored-by: James <james@eli.cx>
2026-06-19 14:49:29 +01:00
Alexander Lichter 388b5c3efb feat(benchmarks): track server bundle sizes (#2173) 2026-06-19 13:23:11 +01:00
James Anderson 53e33babe2 fix(perf): ensure full profiles exist (#2175) 2026-06-19 12:35:08 +01:00
James Anderson 51b2c34958 fix(perf): allow publisher PR comments (#2174) 2026-06-19 11:43:38 +01:00
James Anderson 715ed317ed fix(perf): preserve permissioned cache roots (#2171)
* fix(perf): preserve permissioned cache roots

* fix(perf): run trusted same-repo harness

* fix(perf): ignore reaped benchmark zombies

* fix(perf): profile the build process tree

* fix(perf): wait for benchmark process cleanup

* fix(perf): profile the real build command

* fix(perf): profile the Vite Plus build entry

* fix(perf): avoid nested profiling sudo

* fix(perf): validate traces across profiles
2026-06-19 11:26:38 +01:00
James Anderson a2823aef7c fix(perf): allow isolated Vite task cache (#2170) 2026-06-19 09:26:28 +00:00
Alexander Lichter 44b0c9dcff chore(perf): pair pull request benchmark baselines (#2159)
* fix(perf): pair pull request benchmark baselines

* fix(perf): bootstrap benchmark fingerprint rollout

* fix(perf): harden paired benchmark publishing

* fix(perf): allow isolated build output creation

* fix(perf): transfer isolated build outputs

* fix(perf): verify isolated output permissions

* fix(perf): validate diagnostic trace categories

* fix(perf): retain trusted benchmark manifests

* fix(perf): close benchmark validation gaps

---------

Co-authored-by: James <james@eli.cx>
2026-06-19 10:10:22 +01:00
MaxtuneLee 42f8700f15 fix(router): enhance navigation with as mask for URL handling (#2076)
* fix(router): enhance navigation with `as` mask for URL handling

* fix(router): implement bracket-pattern interpolation for dynamic routes in Pages Router

* fix(router): preserve masked state in beforePopState

* fix(router): cover basepath navigation in ci

* docs(router): clarify navigation state invariants

* refactor(router): require complete history state

* refactor(router): share dynamic href interpolation

* test(router): cover localized masked navigation

* fix(router): keep interpolation internals private

---------

Co-authored-by: James <james@eli.cx>
2026-06-19 00:07:03 +01:00
James Anderson b2ea860284 fix(proxy): match Next.js file conventions (#2155)
* fix(proxy): match Next.js file conventions

* test(proxy): keep convention fixture out of workspace

* test(proxy): provide middleware path in handler fixture
2026-06-18 23:54:39 +01:00
Divanshu Chauhan 7487886b38 fix(prod-server): send headers-only for HEAD in sendCompressed (#1980) (#2058)
sendCompressed wrote the full body for every request. HEAD requests routed
through it (bot/crawler-buffered Pages HTML and Pages API routes) still
compressed and emitted a payload that Node then discards at the socket level.

Short-circuit with res.end() after writeHead when req.method is HEAD,
mirroring sendWebResponse. This skips spinning up a compressor for a body
that would be thrown away and keeps the buffered sender consistent with the
streamed and static-file senders, which already handle HEAD.

Co-authored-by: James <james@eli.cx>
2026-06-18 22:13:07 +00:00
Jerry Zhao 3e5f676666 refactor(shims): normalize the shim alias base to forward slashes on Windows (#2166) 2026-06-18 22:28:25 +01:00
dependabot[bot] a253b9e9e8 chore(deps): bump actions/checkout from 6.0.3 to 7.0.0 (#2161)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: James Anderson <james@eli.cx>
2026-06-18 21:18:42 +00:00
Jerry Zhao b352d671fa fix(rsc): resolve the app-rsc-handler shim to a forward-slash id on Windows (#2165) 2026-06-18 22:18:03 +01:00
Jerry Zhao 2b7faf1ec1 test(font-local): normalize the shim path fixture so the skip guard matches on Windows (#2164) 2026-06-18 22:17:46 +01:00
Jerry Zhao e99b8c6f54 refactor(project): unify directory detection into a shared findDir helper (#2162) 2026-06-18 21:43:11 +01:00
Jerry Zhao ef78685beb test(next-config): build the cacheHandler file:// fixture with pathToFileURL (#2163) 2026-06-18 21:39:37 +01:00
James Anderson c3ff14ec63 docs: add performance best practices (#2157)
* docs: add performance best practices

* Update AGENTS.md

Co-authored-by: Alexander Lichter <alichter@cloudflare.com>

---------

Co-authored-by: Alexander Lichter <alichter@cloudflare.com>
2026-06-18 21:32:32 +01:00
Jilles Soeters 8354b98d64 fix(init): ignore vinext output directory (#2160) 2026-06-18 21:26:05 +01:00
James Anderson 12f04d6d63 fix(app-router): block dangerous RSC redirect URLs (#2154)
* fix(app-router): block dangerous RSC redirect URLs

* refactor(app-router): reuse blocked navigation reporter

* style(app-router): format redirect guard import
2026-06-18 17:51:07 +00:00
James Anderson 44802b7dd6 fix(perf): stabilize stale pull request benchmarks (#2153) 2026-06-18 17:54:47 +01:00