Repository navigation
web: set and enforce a precache bundle budget for the MUI migration #825
Description
Activity
- addedsliceThin vertical work itemThin vertical work itemarea:frontendReact/Vite web clientReact/Vite web clientpriority:tier2High value, low riskHigh value, low riskepic-674SPA revamp — field-first phone, ledger desktop (#674)SPA revamp — field-first phone, ledger desktop (#674)
on Sep 13, 2026 Runtime baseline measured (2026-09-14) — the slope, not the value, is what this slice must watch
Three production builds, 9 runs each, 6x CPU throttling, phone viewport (390x844), timed to the
last Dashboard panel visible. Static build served locally with/apiproxied to a dev API, so the
server and seed data are identical across all three and only the client differs.build wall script style recalc layout precache base, no MUI 917 ms 107 ms 15 ms 26 ms 1312.45 KiB + theme provider only 921 ms 119 ms 15 ms 26 ms 1397.79 KiB + MUI Dashboard (11 components) 919 ms 136 ms 15 ms 25 ms 1436.90 KiB What this settles
- Wall time is flat — 4 ms spread across 27 runs. ~900 ms is network and API, so MUI is
invisible end to end at this scale. - Style recalculation does not move: 15 ms in all three. This retires the concern that
Emotion's runtime CSS injection would be expensive on low-end phones. It is not.
What this slice should therefore budget
Script time is the cost that scales: +12 ms for the provider alone, +29 ms with eleven
components, at 6x throttle — about +5 ms on the device. That is +27% script time for a light
dose of MUI.So a bundle-only budget is the wrong instrument on its own. Recommend this slice sets two
ceilings:- Precache bytes — the number this slice already names.
- Script duration on a reference screen, because it is what actually grows per component and a
byte budget cannot see it.
Re-measure when a screen adopts
Autocompleteor a data grid (#826 is the first): the slope above
is measured onPaper/Typography/Chip/Divideronly, and must not be assumed flat.Method is reproducible — CDP
Performance.getMetricsdeltas around each navigation, median of 9.
Full numbers indocs/decisions/674-ui-component-library.md.- Wall time is flat — 4 ms spread across 27 runs. ~900 ms is network and API, so MUI is
- addedphase:1-groundworkWhole-app decisions before any screen convertsWhole-app decisions before any screen converts
on Sep 14, 2026 - added 4 commits that reference this issue
on Sep 14, 2026 Numbers for the ceiling choice (2026-09-16, head
f502222)Measured on a throwaway worktree with live imports (an upper bound, since some of these components may already be in the bundle after #829/#830):
build precache head 1501.43 KiB + MUI Dialogfamily,Autocomplete,TextField,Tooltip,IconButton1631.76 KiB (+130.3) hand-built Dialog+useConfirm+NamedEntityPicker, isolated as one chunk (what #826/#827 retire)37.5 KB raw JS hand-built NumberField, isolated (what #828 retires)18.2 KB raw JS Projection after #826, #827 and #828 (option (a)): about 1,590 KiB before their CSS is deleted. #835's
opszadds 118.9 on top, so about 1,710. A 1,600 ceiling goes red at #835 and is marginal at #827. 1,800 leaves roughly 90 KiB for the seven remaining screens.Not yet chosen. The owner asked what the ceiling is for and whether it applies to one control or the whole shell; answered in session, recorded here once decided.
Decision (owner, 2026-09-16): measure and report, no gate
The precache total is printed in CI on every web PR (extend
web/scripts/verify-sw.mjs, which already extracts the manifest, to sum the listed files fromdist/and print the KiB), with no threshold. Same shape as backend coverage (#776): a floor picked before enough slices have been measured is a guess, and a wrong guard reads as safety. Revisit a ceiling once the control slices (#826, #827, #828) and #835 have landed and the number has a trend.What this changes in the design doc: D9 ("Ceiling 1,800 KiB, enforced in CI") and the §7 owner-review row are amended when this slice lands. The "a slice that adds more than 10 KiB without deleting code names the reason in its PR body" rule stays as a convention. The script-duration ceiling from the comment above is likewise report-only for now.
Part of #674. Groundwork.
Measured on 2026-09-13 (
docs/decisions/674-ui-component-library.md):+320 KiB precache (+24%) for a full kit. This is a PWA for phones in sheds.
Scope
Runtime cost is a separate question and currently looks fine: at 6x CPU throttling the converted
Dashboard rendered in 1168 ms median vs 1213 ms hand-rolled — inside the noise. Re-measure when a
screen uses
Autocompleteor a data grid.