mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
59cc6420a3
This adds `bench/dev-validation/`, wired as `pnpm bench:dev-validation`, which measures how much dev-mode Cache Components validation contends for the dev server's event loop during rapid navigation, and how much running it on a worker thread relieves that. It toggles `experimental.devValidationWorker` (added in the previous commit) to A/B the two configurations on the same build. Until the worker implementation lands the flag is inert and the A/B shows no delta. The fixture generates one route per family (`client`, `server`, `sprite`), each nested several layout segments deep under a `(routes)` route group. Validation renders a combined payload at every URL depth, so a deeper route means more validation work per navigation, which mirrors a realistically deep app rather than a single flat segment. The runner clicks a family's `<Link>` repeatedly, since navigating to the current route re-renders and re-validates it on every click. The routes carry no `instant` config because dev validation applies to page segments by default at the warning level. The three families isolate the client prerender, the Flight re-encode plus owner-stack work, and the Flight payload size, respectively. The signal is browser-observed TTFB taken from Playwright's own network timing, because it includes the time a request waits for the event loop while validation monopolizes it. We deliberately do not use the CLI's logged request durations: the dev server starts that clock inside the request handler, after the loop has already yielded to the request, so the queue wait is invisible to it. The runner prints each configuration's absolute TTFB (p50/p95/max) side by side rather than a ratio. The time the worker frees is the validation render's CPU, which is bounded, route-dependent, and does no IO, so a ratio would overstate a win that does not scale with total request time. Because the clicks are back-to-back the numbers are a worst case — navigations that land inside the validation window — and the `max` tail is the honest headline: it is the main-thread stall the worker removes.
19 lines
911 B
TypeScript
19 lines
911 B
TypeScript
// The benchmark's route families and the nested segments each route sits under.
|
|
// Keep in sync with scripts/generate.mjs, which generates the matching routes
|
|
// and heavy components. Committed (not generated) so the layout and page
|
|
// type-check on their own.
|
|
//
|
|
// Dev validation renders a combined payload at every URL depth (see
|
|
// `validateInstantConfigs`), so its cost scales with route depth. The routes
|
|
// nest several layout segments to mirror a realistically deep app rather than a
|
|
// single flat segment.
|
|
export const FAMILIES = ['client', 'server', 'sprite'] as const
|
|
|
|
export const NEST_SEGMENTS = ['s1', 's2', 's3', 's4'] as const
|
|
|
|
// The generated routes live in a `(routes)` route group, which does not appear
|
|
// in the URL, so a family's path is just the family segment plus NEST_SEGMENTS.
|
|
export function familyHref(family: string): string {
|
|
return `/${family}/${NEST_SEGMENTS.join('/')}`
|
|
}
|