Bundle size
How many kilobytes of JavaScript and CSS a page actually ships, and therefore how long a phone spends parsing it.
See it
What it is
Bundle size is the total JavaScript and CSS your build pipeline sends to a browser for a given page. Always quote it two ways: transfer size (compressed over the wire, what the download costs) and raw size (the uncompressed bytes). Call raw size a proxy, not 'parse size': only the JavaScript gets parsed, compiled, and executed, so the moment CSS is in the total the label stops being literally true. Still a useful proxy though. A 200KB gzipped JS bundle is roughly 600KB of code the engine has to work through, and on a cheap Android phone that is seconds, not milliseconds.
Look at it when interaction feels late even though the page painted fast. Run a bundle analyzer treemap and you will usually find the same cast: a date library imported whole for one format call, an icon set pulled in via a barrel file, moment or lodash smuggled in by a dependency, two versions of the same package, and a chart library on a page with no chart. Fixes in order of payoff: delete, replace with something smaller, code-split behind a dynamic import, then tree-shake.
The misconception worth killing: bytes are not the cost, they are the proxy. 100KB of images is cheap; 100KB of JavaScript is expensive, because images decode off the main thread while JS has to be parsed, compiled, and run on the one thread your UI lives on. Budget JavaScript far more strictly than everything else, and enforce it in CI as a non-regression check: the build fails the moment a chunk grows past its current ceiling, and you lower the ceiling by hand when you win bytes back. No automatic headroom for growth, because headroom always gets spent.
Ask AI for it
Shrink the JavaScript bundle for this project. Add a bundle analyzer to the build and report the ten largest modules with gzipped and raw sizes. Then apply, in this order: remove dependencies used for one trivial helper, swap heavy libraries for lighter equivalents, replace barrel-file and namespace imports with deep named imports so tree shaking works, dynamic-import anything not needed for the first screen (charts, editors, modals, admin routes), and deduplicate conflicting versions of the same package. Finish by adding a size-limit style budget to CI, pinned to the new measured sizes so any regression fails the build, and lowered by hand whenever you win bytes back. Report before and after gzipped sizes per chunk.