Skip to content

Build transparency

What the build actually makes

A static site is a pile of files, and the pile is countable. This page reads the compiled output and reports it — including the part most sites leave out, which is how many routes are served from a prerendered file and how many are rendered on demand.

Measured from the completed build on 2026-09-12 06:33 UTC (build eoCv1yhT4VQe) by npm run build && npm run measure, and committed as docs/build-report.json. The numbers are not re-derived while the page renders, because a build cannot see its own output.

Routes

155

136 prerendered, 19 on demand

JS chunks

76

3087.1 KB, uncompressed, as emitted

Stylesheets

2

243.4 KB

HTML files

498

24599.7 KB of prerendered markup

What the build compiles in

The static export of this site is, in order: the framework runtime, one shared chunk for the chrome, a chunk per route that needs client code, one stylesheet, two font files, and the prerendered HTML.

  • Framework + shared chrome — React, the router, the header, the footer and the keyframes the demos share. Loaded by every route, demo or not.
  • Per-route client chunks — the demo scene sets, the admin console, the studio panels, the lab tools. 91 routes have none at all.
  • One stylesheet243.4 KB, Tailwind output plus the demo keyframes, shared by every page and cached immutably.
  • Two fonts80 KB, latin subsets, preloaded on 497 pages.

The six heaviest prerendered pages

HTML weight is not only JavaScript: a page that renders 74 posters is large before anything runs.

Data table — data table
FileSize
admin/health.html1168.1 KB
quality.html916.7 KB
components/kind/element.html504.7 KB
prompts.html453.9 KB
sitemap.html430 KB
quality/refreshed.html376.5 KB

The shared shell, under a recorded budget

The shell is the file set the most routes start from, measured from the compiled entry manifests. Its budget is recorded in the build report next to the measurement — not copied from it — and the export harness fails a build that grows the shell past it.

Measured shell

690.1 KB

this build

Budget

730 KB

39.9 KB of headroom

The shell (the file set the most routes share) is measured from the entry manifests and capped at the budget recorded next to it; the export harness fails a build that grows the shell past it.

Share cards

562

one per asset, plus the site fallback

Heaviest card

101.6 KB

2026-09-12-bank-3-batch-8-25-navigation-and-layout-components-land

Budget

120 KB

per card, fetched with no cache warm

Mean

82.2 KB

46223.1 KB across all 562 cards

The eight heaviest cards

A share card is fetched by a crawler with no cache warm, so the heaviest card is the number that matters. The budget is recorded in the build report and the export harness fails a build that ships a card over it.

Data table — data table
CardSize
2026-09-12-bank-3-batch-8-25-navigation-and-layout-components-land101.6 KB
2026-09-12-bank-3-batch-10-closes-the-scenes-backgrounds-section101 KB
2026-09-09-overlay-widgets-land-command-palette-toasts-sheet-menu99.8 KB
2026-09-12-bank-3-batch-15-the-stack-workbench-and-the-studio-pass98.9 KB
2026-09-12-bank-3-batch-9-25-scenes-and-backgrounds-land98.2 KB
2026-09-12-bank-3-batch-7-25-data-display-components-land97.9 KB
the-60fps-handshake97.4 KB
2026-09-12-bank-3-batch-19-admin-ops-the-content-operations-shelf97.3 KB

No card exceeds the 120 KB budget.

How this is measured

next build                    → compiles routes, chunks, HTML
perf.ts routeBudgets()        → reads each route's compiled entry files
perf.ts collectHtml()         → walks .next/server/app for *.html
perf.ts fontAudit()           → reads the emitted woff2 files and the preload links

Every figure on this page comes from one of those three reads. A route that has no entry manifest is missing from the table rather than estimated, and a route with no prerendered HTML is labelled “on demand” rather than counted as static.

The weight of a page, in one read

Take the measured baseline route: it starts from the shared shell, adds its own chunks, and carries one stylesheet that every route shares. The table above is that arithmetic per route — own JS is what a route adds beyond the shell, total JS is what a cold visit pays, and HTML is the document itself. The same three numbers, plus the fonts, are what the budgets gate on.

  • • #408 — script order: two inline scripts on the shell (the theme bootstrap), everything else is a hashed file with an integrity-safe load order Next controls.
  • • #415 — delivery: plain CSS, one sheet, no CSS-in-JS runtime; the trade-off and its bytes are recorded on /quality/speed.
  • • #416 — hydration: demos hydrate where they render, behind the lazy loader; pages without a demo ship no scene code at all.

The asset inventory

#404 — every emitted script and style is fingerprinted by filename, so the inventory below is the whole delivery surface: nothing is fetched by a name that can go stale, and a hash that stops appearing is a chunk that stopped shipping.

js chunks: 71 · css: 2 files · fonts: woff2 ×2 · HTML documents: 472

#402 — the shell ratchet, every re-record written down: 446.8 (batch 92) → 502.2 → 546.9 → 580.9 → 603.8 → 641.9 → 675.3 KB after #410 split the prompt catalog out of the shared chunk — the series that was climbing with every content batch now has structural headroom instead of a moving target.

Perf runbook, plans and the FAQ

#414 — when a budget fails

1. re-measure clean. 2. attribute the chunk. 3. revert or re-record with a written rationale. Never re-record silently.

#419 — the FAQ

Why one stylesheet? 219 KB shared beats per-route CSS at this scale. Why no images? The catalog is SVG. Why no worker? A cache without invalidation is a stale catalog.

#411 — a build-time CI budget env

Wall-clock gates need a reference machine; this sandbox is not one. The plan is written, the number is not faked.

#417/#418 — field plans env

Long-session heap and Core Web Vitals field data both need a real domain and traffic. The collection plan is written; the numbers wait for the origin.