feat(scripts): add a client-bundle measurement so regressions are visible - #6135
feat(scripts): add a client-bundle measurement so regressions are visible#6135waleedlatif1 wants to merge 1 commit into
Conversation
…ible Nothing measured the JavaScript we ship. Turbopack's route table prints only Revalidate/Expire — no `First Load JS` — and it emits flat, content-hashed chunk names with no app-build-manifest.json, so there is no route->chunk mapping to attribute bytes with. @next/bundle-analyzer is a webpack plugin and is not installed. A bundle regression was therefore invisible until a user noticed a slow page. `bun run measure:bundle` reports total client JS and the largest chunks; `--json` emits a baseline and `--baseline <file>` fails on a >2% regression, so this can become a CI gate once a baseline is agreed. Deliberately not per-route. That needs either a manifest Turbopack does not emit or a browser loading each route; inventing an attribution from flat chunk names would produce a confident number that is wrong. First use already paid for it. Building twice — once normally, once with the existing SIM_DEV_MINIMAL_REGISTRY alias forced on — measures what the tool and block registries cost the client: baseline 110.08 MB across 553 chunks registries aliased away 52.96 MB across 553 chunks (-51.9%) The four 15.52 MB chunks in the baseline disappear entirely; they are the registry graph duplicated across four entry points. That is an upper bound for both registries together, not a promise — a metadata split would still ship params/outputs for referenced tools — but it establishes that the registry is roughly half of all client JS, measured rather than inferred from an import-graph tracer.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryLow Risk Overview The script walks Reviewed by Cursor Bugbot for commit 32afd8d. Configure here. |
Greptile SummaryAdds a client-bundle measurement command.
Confidence Score: 4/5The PR appears safe to merge, with a non-blocking CLI composability issue where JSON output bypasses a requested baseline check. Bundle measurement works for the documented standalone modes, but combining machine-readable output with regression enforcement exits before performing the comparison. Files Needing Attention: scripts/measure-client-bundle.ts
|
| Filename | Overview |
|---|---|
| scripts/measure-client-bundle.ts | Adds bundle traversal, reporting, and baseline enforcement; combined JSON and baseline flags silently skip enforcement. |
| package.json | Adds the measure:bundle script entry with no issue identified. |
Reviews (1): Last reviewed commit: "feat(scripts): add a client-bundle measu..." | Re-trigger Greptile
| if (args.includes('--json')) { | ||
| process.stdout.write(`${JSON.stringify(report, null, 2)}\n`) | ||
| return | ||
| } |
|
Closing — this measures but doesn't fix, and as written it isn't wired into CI with a committed baseline, so in practice nobody would run it. That makes it tooling that implies we measure bundles when we don't. The measurement already paid for itself as a one-off: 110.08 MB -> 52.96 MB with the registries aliased away (~52% of all client JS), which confirmed the premise from a real build rather than an import-graph tracer. That number is captured; the script can be reproduced locally when the split needs a before/after. If we want an actual regression guard later, the right shape is a committed baseline plus a CI step — a deliberate decision, not a side effect of a scoping exercise. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 32afd8d. Configure here.
|
|
||
| const __filename = fileURLToPath(import.meta.url) | ||
| const rootDir = path.resolve(path.dirname(__filename), '..') | ||
| const chunkDir = path.join(rootDir, 'apps/sim/.next/static/chunks') |
There was a problem hiding this comment.
Misses immutable chunk directory
Medium Severity
chunkDir is hardcoded to apps/sim/.next/static/chunks, but the current build also emits a parallel static/immutable/chunks tree (including app/, pages/, and turbopack/). Client JS under that prefix is never counted, so totals and the baseline gate can miss real payload growth.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 32afd8d. Configure here.


Summary
We ship JavaScript to users and nothing measures it. This adds
bun run measure:bundle, and its first use already produced a decisive result: the tool and block registries are ~52% of all client JS.Why this didn't exist
Every instrument you'd reach for is missing:
First Load JSin build outputapp-build-manifest.json(route→chunk map)static/chunks/app/**1ep92zb9a-584.js)@next/bundle-analyzerSo a bundle regression was invisible until someone noticed a slow page.
What it measures
Total client JS plus the largest chunks.
--jsonwrites a baseline;--baseline <file>fails on a >2% regression, so it can become a CI gate once a baseline is agreed.Deliberately not per-route. That needs either a manifest Turbopack doesn't emit, or a browser loading each route. Inventing an attribution from flat chunk names would produce a confident number that is wrong — worse than no number.
.mapfiles are excluded, so a source-map change can't masquerade as a bundle regression.First result: the registry premise, measured
Two production builds — one normal, one with the existing
SIM_DEV_MINIMAL_REGISTRYalias forced on:The four 15.52 MB chunks in the baseline vanish completely — that's the registry graph duplicated across four entry points.
How to read that number honestly
@/tools/registryand@/blocks/registry-maps), not tools alone, and not a promise. A metadata split would still shipparams/outputsfor referenced tools.Why this matters beyond one project
The registry split was scoped on an unverified premise. This makes the premise checkable, gives the work a before/after, and leaves behind a regression guard that outlives it.
Type of Change
Testing
Run against two real production builds (numbers above).
biome checkclean. No dependencies added.next.config.tswas temporarily modified for the second build and restored — the diff is only the new script and itspackage.jsonentry.