Crux Read real bundler config, import patterns, a size-limit CI snippet, and a Priority header, predict the effect on shipped bytes, and pick the highest-leverage fix.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at senior altitude — in orbit
◷ 14 min
Bundle problems are diagnosed in config files, import lines, the analyzer treemap, and the CI log. Read each snippet the way a senior would, then pick the fix that actually moves shipped bytes — not the one that only moves the wire.
Goal
Practise the loop you run in every bundle review: read the import or config, predict whether it ships dead weight, and reach for the highest-leverage fix — split or shake the bytes before you reach for compression or a knob.
Snippet 1 — the barrel re-export
// components/index.tsexport * from './Button';export * from './Modal';export * from './RichTextEditor'; // pulls in a 180 KB editor lib// consumerimport { Button } from '@/components'; // only Button is used here
Quiz
Completed
The route only uses Button, yet the analyzer shows the 180 KB editor in this chunk. What is happening, and what is the fix?
Heads-up Button does not import the editor. The barrel's `export *` is what drags the editor into the graph for any consumer of the barrel.
Heads-up `export *` barrels frequently defeat tree shaking: the bundler keeps the re-exported modules when even one barrel export is consumed. The editor ships.
Heads-up sideEffects: false helps with module-scope side effects, not with a barrel that statically re-exports a used module's siblings. Fix the re-export.
Snippet 2 — the dynamic import
// loads a chart panel that is not on first paintfunction openPanel(name) { return import(`./panels/${name}`); // variable in the specifier}// elsewhere, a true lazy boundaryconst Editor = React.lazy(() => import('./Editor'));
Quiz
Completed
Both lines look like code splitting. Which one actually produces a clean, individually-shakeable chunk, and why?
Heads-up A runtime-variable specifier makes the target unknowable at build time, so the bundler must include the whole matched directory in one chunk. Only the string literal splits cleanly.
Heads-up Flexibility is the cost here: the variable form bundles the entire ./panels folder. The string-literal `import('./Editor')` is the one that yields a precise chunk.
Heads-up React.lazy is built on dynamic import() and is exactly how you split a component. The string-literal import is the clean one.
A PR triggers this output. The author asks to merge and 'fix it next sprint'. What is the correct senior response?
Heads-up Each named limit is independent; the homepage limit failed. A passing aggregate does not excuse a per-route regression.
Heads-up Self-approving a raise in the offending PR defeats the gate. A raise requires the budget-raise protocol: documented justification and performance-lead sign-off.
Heads-up Bypassing the gate destroys its value — budgets erode one bypass at a time. The point is that every change is visible and explicit.
Snippet 4 — the HTTP/3 priority
# Browser request for the critical app chunkGET /_next/static/app.abc123.jsPriority: u=1# Browser request for a large deferred vendor chunkGET /_next/static/vendor.def456.jsPriority: u=5# CDN config (misconfigured): ignores client Priority, serves FIFO
Quiz
Completed
The app is correctly code-split and the browser sends sane RFC 9218 priorities, but the CDN ignores them and serves first-come-first-served. What is the likely impact and where do you verify it?
Heads-up HTTP/3's transport gains don't help if priority hints are ignored: bandwidth is shared equally and the critical chunk loses its head start.
Heads-up Without honored priorities, ordering is non-deterministic / FIFO — size does not push it last. Correct priorities are what would order the small critical chunk first.
Heads-up Un-splitting reintroduces the full parse cost on the critical path. The fix is to make the CDN honor priorities, not to abandon splitting.
Recap
Every bundle regression is read in config and output: export * barrels and runtime-variable dynamic imports silently defeat splitting and tree shaking; a size-limit failure is a hard gate, not a suggestion to defer; and even a perfectly split bundle underdelivers if the CDN ignores HTTP/3 priorities. Diagnose from the analyzer and the CI log, fix by removing bytes from the critical path first, then confirm delivery order — re-measure rather than assume.