Canonical source: libs/oshun/analytics/src/v3-web-first-load-budget.ts
Manifest version: v3-web-first-load-budget.v1
The GA web first-load gate validates the root V3 web route on the required
desktop and mobile profiles. The p95 budgets are normative; the committed
"observed" figures are hand-authored projections — the corresponding
V3/V3_TODOS.md §66 task is [~] and V3/VERIFICATION_AUDIT_2026-05-31.md
confirmed no real-device run exists. Real-device measurement is pending.
| Profile | Device | Network | p95 budget | Projected p95 (measurement pending) |
|---|---|---|---|---|
m1-mac-broadband |
M1 Mac | Broadband | <= 8,000 ms | 6,940 ms |
pixel-7-cellular |
Pixel 7 | Cellular | <= 12,000 ms | 10,860 ms |
Methodology#
- Metric. First load is wall-clock time from navigation start to the V3 web
shell reaching interactive render of the root route (
/) on a cold HTTP cache and cold service-worker state: no prioroshun-v3-tier2-cache-v1entries, no warm DNS/TLS session. Each sample is one full cold navigation in a fresh browser context. - Percentile definition. p95 is computed per profile over the full sample set using nearest-rank on the sorted first-load times. A profile passes only if p95 <= its budget; the per-sample max and sample count are retained in the evidence so percentile consistency can be re-checked.
- Sample count. >= 30 samples per profile is the manifest floor
(
minSampleCount); the committed evidence set declares 60 samples per profile. Runs below the floor are rejected. - Device / network profiles.
m1-mac-broadband: Apple M1 macOS, Chromium-engine browser, unthrottled broadband (>= 100 Mbps, < 20 ms RTT to the nearest edge).pixel-7-cellular: Pixel 7 Android, Chrome, cellular profile throttled to sustained 4G (~9 Mbps down / 170 ms RTT), matching the §66 budget's "Pixel 7 cellular" wording.
- Measurement procedure. For each profile: (1) deploy the production build
of the V3 web app (
apps/v3/lilith-web); (2) clear browser storage, caches, and service workers; (3) navigate to the root route and record navigation-start → interactive-render time via the Playwright trace (apps/v3/lilith-web-e2efirst-load spec, with source parity coverage in the Tier-2 fallback shell); (4) repeat for the full sample count, discarding no samples; (5) write per-sample timings, sample count, p95, andmeasuredAtIsointo the evidence consumed by the manifest. This mirrors the deterministic-harness structure ofV3/COLD_JOIN_VALIDATION.md, but unlike cold join it requires the real devices and network shaping above — which is why it is measurement-pending rather than locally verified.
The evidence path is apps/v3/lilith-web/e2e/lilith-web-shell.spec.ts, with
source parity coverage in the Tier-2 fallback shell. The verifier
(pnpm verify:v3 web-first-load-budget) fails closed when a required profile is
missing, p95 exceeds budget, sample count is below the profile floor, CI is not
green, or percentile evidence is malformed. When the real-device runs land,
replace the projected column with measured values and drop the
measurement-pending caveat.