Skip to content

perf(app-router): defer post-middleware cookie materialisation#2490

Draft
NathanDrake2406 wants to merge 3 commits into
cloudflare:mainfrom
NathanDrake2406:nathan/postmw-cookie-materialization
Draft

perf(app-router): defer post-middleware cookie materialisation#2490
NathanDrake2406 wants to merge 3 commits into
cloudflare:mainfrom
NathanDrake2406:nathan/postmw-cookie-materialization

Conversation

@NathanDrake2406

@NathanDrake2406 NathanDrake2406 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Overview

Area Change
Goal Avoid post-middleware cookie/query materialisation when config predicates do not need it.
Core change Track cookie/query access per config rule and expose lazy post-middleware request context getters to rewrite matching.
Safety boundary Cookie predicates that can run after no-JS progressive action code still materialise the post-middleware cookie snapshot before action dispatch.
Primary files config-matchers.ts, app-post-middleware-context.ts, app-rsc-handler.ts
Expected impact Removes one request cookie parse from route/document paths with no cookie config predicates in the Worker app router profile.

Why

has and missing predicates are the only config rewrite checks that need request cookies or query params. The post-middleware request context was materialising cookies and query state even when the matching rule could only inspect path/header/host state. On Workers this showed up as a fixed per-request cookie parse on ordinary route and document requests.

What changed

Surface Before After
Post-middleware context Object.fromEntries(ctx.cookies) and url.searchParams were built eagerly. Cookies and query are lazy memoized getters.
Rewrite matching Every resolved rewrite context exposed cookies/query regardless of the rule. Each rule carries a cached cookie/query access pre-scan, and unused stores are hidden behind empty values.
Progressive actions Lazy cookies could otherwise observe action-time cookie mutations before late rewrites. Source-matching late cookie predicates materialise the post-middleware cookie snapshot before action dispatch.

Evidence

Local Worker evidence run from tests/fixtures/app-basic, workerd via the existing app-router Worker harness, 500 measured requests, 50 warmup, concurrency 4. Latency is local and noisy, so the deterministic counter is the important signal.

Scenario Request cookie parses/request before Request cookie parses/request after
route /api/hello 1.00 0.00
document /about 1.00 0.00
cookie beforeFiles hit after middleware 1.00 1.00
cookie fallback hit after middleware 1.00 1.00
missing-cookie header predicate 1.00 0.00

Final candidate counter run also kept cookie-gated rewrite scenarios at 1.00 request cookie parse/request and route/document at 0.00.

Validation

  • vp check tests/app-post-middleware-context.test.ts tests/app-rsc-handler.test.ts tests/shims.test.ts packages/vinext/src/config/config-matchers.ts packages/vinext/src/server/app-post-middleware-context.ts packages/vinext/src/server/app-rsc-handler.ts
  • vp test run tests/app-post-middleware-context.test.ts tests/app-rsc-handler.test.ts tests/shims.test.ts -t "cookie-gated rewrite|post-middleware cookie snapshot|does not materialise middleware cookies|reports cookie and query condition access separately"
  • vp test run tests/app-post-middleware-context.test.ts tests/app-rsc-handler.test.ts
  • vp run vinext#build
  • Pre-commit hook: staged checks, full check, staged unit/integration tests, knip
  • Worker benchmark smoke with VINEXT_APP_ROUTER_WORKER_EVIDENCE_REQUESTS=500, WARMUP=50, CONCURRENCY=4

Post-middleware request context eagerly materialised cookies and query state even when config has/missing predicates did not need them. On Workers this added per-request cookie parsing on route and document paths with no cookie conditions.

Track whether each config rule can read cookies or query params, expose lazy cookies/query to rewrite matching only when needed, and pre-materialise cookies before progressive action dispatch when a late rewrite predicate could otherwise observe action-time cookie mutations.

Adds regression coverage for middleware-mutated cookie rewrites, lazy post-middleware cookie materialisation, late progressive-action cookie snapshots, and condition access scanning.
@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@vinext/cloudflare@2490
npm i https://pkg.pr.new/vinext@2490

commit: 47ad6e3

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared 47ad6e3 against base 239595e using alternating same-runner rounds. Next.js was unchanged and skipped.

1 improved · 0 regressed · 5 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 125.6 KB 125.6 KB ⚫ +0.0%
Client entry size (gzip) vinext 119.8 KB 119.8 KB ⚫ +0.0%
Dev server cold start vinext 2.53 s 2.48 s 🟢 -2.0%
Production build time vinext 3.04 s 3.05 s ⚫ +0.4%
RSC entry closure size (gzip) vinext 96.8 KB 97.1 KB ⚫ +0.3%
Server bundle size (gzip) vinext 163.2 KB 163.5 KB ⚫ +0.2%

View detailed results and traces

🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant