Commit Graph

1420 Commits

Author SHA1 Message Date
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
Alexander Lichter 2fc9845ed3 fix(fonts): preload only requested google font subsets (#2152)
Co-authored-by: James Anderson <james@eli.cx>
2026-06-18 17:20:05 +01:00
MK (fengmk2) 6fff7bb88f chore: upgrade vite-plus to 0.2.1 (#2149)
v0.2.1 consumes upstream Vitest directly: the @voidzero-dev/vite-plus-test wrapper is removed and vitest now comes in transitively through vite-plus.

- catalog: vite-plus 0.1.24 -> 0.2.1, vite -> @voidzero-dev/vite-plus-core@0.2.1
- catalog: vitest -> upstream 4.1.9 (was the vite-plus-test alias), @vitest/coverage-istanbul 4.1.6 -> 4.1.9
- drop the vitest peerDependencyRules accommodations for the wrapper/old vitest
- decode Vitest's flatted blob format directly in scripts/lib/vitest-blob-timings.mjs (the removed wrapper bundled the parser this script previously reached into)
2026-06-18 16:37:34 +01:00
Alexander Lichter 9639c88231 perf(app-router): defer prerender endpoint & file metadata runtimes (#2150)
* perf(app-router): defer prerender endpoint runtime

* perf(app-router): defer file metadata runtimes
2026-06-18 16:30:03 +01:00
Nathan Nguyen 00f0a684e0 test(ppr): wait for fallback shell abort signal (#2072) 2026-06-18 15:07:56 +01:00
MaxtuneLee ef003c0ebe fix(server): q-value-aware Accept-Encoding negotiation (#2047)
* fix(server): implement q-value-aware Accept-Encoding negotiation and add tests

* docs(server): update comments for Accept-Encoding parsing to clarify q-value handling

* fix(server): enhance q-value handling in Accept-Encoding parsing and add tests

* fix(server): enhance q-value handling in Accept-Encoding parsing and add tests for isEncodingAccepted

* fix(tests): update negotiateEncoding tests to reflect zstd as highest preference in prod-server.ts

* fix(tests): update negotiateEncoding tests

* fix(tests): remove redundant test for explicit refusal overriding wildcard in negotiateEncoding

* fix(server): normalize encoding checks in isEncodingAccepted function

* refactor(server): extract accept-encoding helpers

* fix(tests): remove redundant zlib check and import HAS_ZSTD from accept-encoding module

* fix(server): honor Accept-Encoding quality weights

* fix(server): repair accept-encoding CI checks

* fix(server): harden content encoding negotiation

* fix(server): align encoding negotiation with Next.js

* refactor(server): remove unused encoding parse state

* fix(server): normalize empty vary headers

---------

Co-authored-by: James <james@eli.cx>
2026-06-18 14:07:05 +01:00