Skip to main content
A SHA alone gives false continuity. Bundle sizes move with lockfiles, Next upgrades, Node versions and config edits at the same commit. So a build id hashes everything that can change the numbers:
The dirty-tree component matters most in practice. Most measuring happens on uncommitted work, and keying on the SHA alone makes ten experiments overwrite each other under one identity.
Outside a git repository, a content fingerprint of the emitted chunk filenames stands in — those are content-hashed by both bundlers, so it changes exactly when the output does.

Run identity

A build can be measured many times. Each synthetic run gets a sortable id and an environment fingerprint:
Runs with different environment fingerprints must never be merged into one trend line. A laptop on battery versus CI looks exactly like a regression that is not one.

Route identity

Trends are keyed on the page file path, not the URL pattern:
Patterns change during refactors, and keying on them would silently restart the history. When a file itself moves, .perf/aliases.json stitches it back.

Orphaned history

Squash merges destroy the pre-squash SHAs, so ancestry lookup finds nothing. Every snapshot also stores a sourceSignature — a hash of the route table and module set — so an orphaned baseline can be re-linked by content.