mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
build: budget the routes on measured drift, not on a ceiling they touch
Three of the four watched routes sat within a kilobyte of their ceiling —
444 of 445, 459 of 460, 459 of 460 — because the numbers had been re-stated
for four releases and never re-based. A budget a route is already touching
does not measure the route; it measures whichever dependency bump landed that
week. e2e run 34043772954 failed on `/insights/page: 445 KB gz exceeds the
445 KB budget` with nothing in the diff that touched the bundle, and it was one
of at least four e2e failures that were the budget gate rather than a test.
The file states the measured value per route now, plus one drift allowance over
it, and a route fails on the delta. Measured on a local build at d48bbff01:
/ 447, /insights 434, /measurements 433, /insights/mood 447, allowance 20 KB, so
the effective ceilings are 467 / 454 / 453 / 467 — a raise for all four. The
allowance covers the runner delta and ordinary week-to-week drift; the step
change the gate exists for, a statically imported catalog or a duplicated chart
library, is several times larger and still fails. Every run prints the delta, so
a route that has crept most of the way through its allowance is legible in the
log long before it is red. The reason and the re-base instructions are written
into the file's running note, as with every raise before it.
A budget file with no baselines used to gate nothing quietly, since the loop
had nothing to walk; it now refuses.
Gates, against the current build:
real baselines passed; /page +0.3, /insights +0.3,
/measurements +0.2, /insights/mood +0.3 KB
/page baseline 425 (cap 445), FAILED: "/page: 447 KB gz is 21.6 KB over the
/insights 413 (cap 433) 425 KB baseline, past the 20 KB drift
allowance (cap 445 KB)" and the same for
/insights/page, exit 1
routeBaselineKbGz removed exit 2, "states no routeBaselineKbGz entries,
so no route is gated"
This commit is contained in:
1 parent
626a95ff33
commit
69aac232b4
2 files changed
+55
-17
No files matched your search
@@ -23,11 +23,20 @@
|
||||
* pnpm bundle-report # print the report table
|
||||
* pnpm bundle-report --check # enforce bundle-budget.json (CI gate)
|
||||
*
|
||||
* Budgets live in `bundle-budget.json` (repo root). Numbers are KB gzip
|
||||
* with deliberate headroom over the measured value — the gate exists to
|
||||
* catch step-change regressions (a ~100 KB catalog, a ~90 KB duplicate
|
||||
* library), not day-to-day noise. Raise a budget consciously, in the same
|
||||
* PR that pays the cost, with the reason in the PR body.
|
||||
* Budgets live in `bundle-budget.json` (repo root). Numbers are KB gzip.
|
||||
*
|
||||
* Per-route the file states a MEASURED baseline and one drift allowance
|
||||
* over it, and a route fails on the delta rather than on a ceiling it is
|
||||
* already touching. Flat ceilings had been re-stated but never re-based, so
|
||||
* three routes ended up sitting within a kilobyte of theirs and any
|
||||
* unrelated dependency bump failed the e2e job on a regression nobody had
|
||||
* made. The delta is printed on every run, so a route that has crept most of
|
||||
* the way through its allowance is readable in the log before it is red.
|
||||
*
|
||||
* The gate still exists to catch step changes (a ~100 KB statically imported
|
||||
* catalog, a ~90 KB duplicate library), which are several times the
|
||||
* allowance. Re-base consciously, in the same PR that pays the cost, with
|
||||
* the reason written into `$comment`.
|
||||
*/
|
||||
|
||||
import { readFileSync, readdirSync, existsSync } from "node:fs";
|
||||
@@ -166,14 +175,28 @@ console.log(
|
||||
console.log(`recharts-fingerprint chunks: ${rechartsChunks}`);
|
||||
console.log("");
|
||||
|
||||
const watched = budget ? Object.keys(budget.routesKbGz ?? {}) : [];
|
||||
const baselines = budget?.routeBaselineKbGz ?? {};
|
||||
const allowanceKb = budget?.routeDriftAllowanceKbGz ?? 0;
|
||||
/** The ceiling a route's measured baseline plus the drift allowance buys it. */
|
||||
const capFor = (route) =>
|
||||
baselines[route] == null ? null : baselines[route] + allowanceKb;
|
||||
|
||||
const watched = Object.keys(baselines);
|
||||
const rows = [...routeTotals.entries()]
|
||||
.filter(([route]) => !watched.length || watched.includes(route))
|
||||
.sort((a, b) => b[1].gz - a[1].gz);
|
||||
for (const [route, { gz }] of rows.slice(0, watched.length || 15)) {
|
||||
const cap = budget?.routesKbGz?.[route];
|
||||
const baseline = baselines[route];
|
||||
if (baseline == null) {
|
||||
console.log(`${fmt(gz).padStart(8)} gz ${route}`);
|
||||
continue;
|
||||
}
|
||||
const delta = kb(gz) - baseline;
|
||||
const sign = delta >= 0 ? "+" : "−";
|
||||
console.log(
|
||||
`${fmt(gz).padStart(8)} gz ${route}${cap ? ` (budget ${cap} KB)` : ""}`,
|
||||
`${fmt(gz).padStart(8)} gz ${route} (baseline ${baseline} KB, ` +
|
||||
`${sign}${Math.abs(delta).toFixed(1)} KB of ${allowanceKb} KB allowed, ` +
|
||||
`cap ${capFor(route)} KB)`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -185,16 +208,30 @@ if (!budget) {
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
// A budget file that states no baselines gates nothing, and would do it
|
||||
// quietly — the loop below would simply have nothing to walk. Say so instead.
|
||||
if (watched.length === 0) {
|
||||
console.error(
|
||||
"check-bundle-budget: bundle-budget.json states no routeBaselineKbGz " +
|
||||
"entries, so no route is gated. Measure the eager routes and write " +
|
||||
"them in, with a routeDriftAllowanceKbGz over them.",
|
||||
);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const failures = [];
|
||||
for (const [route, capKb] of Object.entries(budget.routesKbGz ?? {})) {
|
||||
for (const [route, baselineKb] of Object.entries(baselines)) {
|
||||
const actual = routeTotals.get(route);
|
||||
if (!actual) {
|
||||
failures.push(`route ${route} not found in the build output`);
|
||||
continue;
|
||||
}
|
||||
if (kb(actual.gz) > capKb) {
|
||||
const delta = kb(actual.gz) - baselineKb;
|
||||
if (delta > allowanceKb) {
|
||||
failures.push(
|
||||
`${route}: ${fmt(actual.gz)} gz exceeds the ${capKb} KB budget`,
|
||||
`${route}: ${fmt(actual.gz)} gz is ${delta.toFixed(1)} KB over the ` +
|
||||
`${baselineKb} KB baseline, past the ${allowanceKb} KB drift ` +
|
||||
`allowance (cap ${capFor(route)} KB)`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user