Skip to content

The Lab · instrumentation

Which properties leave the main thread

A scene that animates transform is handled by the compositor; one that animates width or box-shadow makes the browser paint the frame. Pick any demo from the catalog, mount it here, and the inspector reads every node it creates and says which side of that line it falls on.

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.

@keyframes in the project

139

across 13 files

Animation declarations

224

92 of them run forever

Transitions classified

94

48 compositor · 31 paint · 14 layout

will-change hints

7

explicit requests for a layer

Prism is on

How the source scan reads

transition: transform .3s   → compositor
transition: box-shadow .3s → paint
transition: width .3s      → layout
animation: spin 4s infinite → name recorded, properties unknown

The 94 transition declarations above are classified by the property they name, which is the only part a stylesheet states. A transition on all is counted as compositor-safe because that is what the shorthand usually targets — and that is a judgement, so it is written here rather than buried in the number.

Why this matters for this library

The demo scenes are 15,653 lines across 17 modules — they were one file until batch 85 split them so a page loads only the set it renders — and 92 of the project's animations run forever by design — ambient loops, drifting gradients, marquees. Ambient motion that stays on the compositor costs almost nothing; ambient motion that repaints does it every frame, on every page it appears on, for as long as the tab is open. That is the entire reason the audit exists, and it is measurable in the panel above rather than argued about.

The blur budget →

The inspector component is src/components/layer-inspector.tsx and the source scan is motionAudit() in src/lib/perf.ts. Because the inspector mounts a real demo, this page is the route in the section that pulls a scene set rather than rendering none — and since batch 85 that means the set it mounts, not all ten of them. The budget page reports that cost rather than hiding it.