BXUP Track progress & test yourself — free
Frontend & Mobile · Playbook · Core · ~5 min read
FRONTEND & MOBILE · PLAYBOOK · CORE

Bundle-Size Investigation: Ranked Plan, Then Measure

Your main bundle crossed a megabyte and nobody can say why. Bundle analyzers tell you what is in there; an LLM is good at turning that inventory into a ranked reduction plan — duplicates, heavy dependencies, missed split points. Every item on the plan is then verified by building and measuring, because models routinely propose savings that bundlers already made or that break behavior.

Tier: Core · Workflow area: Performance & debugging

This playbook turns bundle archaeology into a short, evidence-ranked backlog and closes each item with a measured before/after.

When to use

  • First-load JS has crept past your budget (or you are setting a budget and need to earn headroom first).
  • Lighthouse flags "Reduce unused JavaScript" and the LCP/INP work (pb-34, pb-36) traced back to script weight.
  • A dependency bump or new feature caused a step-change in bundle size and you need attribution.
  • You inherited a frontend with no history of bundle discipline.

Skip it if your problem is one known heavy import — just fix it. This playbook is for when the weight is diffuse and unexplained.

Prerequisites

  • A production build you can run locally, with source maps emitted — the analysis is worthless against dev builds.
  • One analyzer wired up: source-map-explorer for any bundler with source maps, rollup-plugin-visualizer for Vite/Rollup, @next/bundle-analyzer for Next.js, or webpack-bundle-analyzer.
  • The baseline numbers recorded before any changes: total JS transferred (gzip/brotli), main/entry chunk size, and the top 10 modules by size.
  • A definition of what you are optimizing: first-load JS on the critical route, not total build output. Lazy-loaded admin panels are not the enemy.

The workflow

  1. Generate the inventory and capture the baseline. Build for production and run the analyzer. Export something textual — source-map-explorer --json, the visualizer's data file, or even the sorted module list — because the next step needs data the model can read, not a treemap screenshot alone (though attaching the screenshot too helps a multimodal model).

  2. Ask for a ranked plan with claimed evidence per item. Feed the inventory with a prompt that forces structure and falsifiability:

    This is the bundle analysis of our app's critical route (JSON attached;
    totals: 1.14MB raw / 342KB gzip first-load). Produce a ranked reduction
    plan. For each item give:
    1. What to change (specific: package, import site, config).
    2. Estimated savings in KB and your confidence.
    3. The evidence in this data that supports it (module paths, sizes).
    4. Risk: what could break, and how to check.
    Look specifically for: duplicate packages at multiple versions,
    multiple libraries doing the same job (date, utility, icons), full-library
    imports where subpath imports exist, polyfills for targets we may not
    need, heavy deps used on this route but only for a minor feature, and
    components that are candidates for dynamic import.
    

    Cross-examine the top items: npm why <package> for duplicates, grep for the import sites it names. Strike any item whose evidence you cannot reproduce in the data.

  3. Verify the top item with a measurement, not a merge. Take the highest-ranked item, apply it on a branch, rebuild, re-run the analyzer, and compare against the baseline. Watch for the two classic false wins:

    • Already-shaken code: the model sees a big library in the inventory and proposes "import only what you use" — but the inventory may already reflect tree-shaken reality. The rebuild tells the truth.
    • Moved, not removed: dynamic-importing a component saves first-load only if nothing else on the route still imports it statically. Check the chunk graph, not just the total.
  4. Work down the list, one measured change per PR. Each PR carries the before/after: raw and compressed sizes, and which chunk changed. Behavioral risk items (swapping a date library, dropping a polyfill) additionally need the check the plan named in its risk column — run the affected tests or the affected browser matrix before merging.

  5. Install the ratchet. Once you have won the headroom, freeze it: size-limit, bundlesize, or your CI's budget assertion on first-load JS per critical route, set just above the new reality. Add the analyzer to CI as an artifact so the next investigation starts with history instead of archaeology.

Key Takeaway:

The model ranks, the build measures. An LLM reading your bundle inventory finds real duplicates and split points fast — and also confidently proposes savings the bundler already made. Nothing lands without a rebuilt, re-measured before/after.

Tool variants

  • source-map-explorer: bundler-agnostic and honest — it measures what actually shipped via source maps. Best default for the inventory.
  • rollup-plugin-visualizer / @next/bundle-analyzer / webpack-bundle-analyzer: framework-native treemaps plus data files; the visualizer's JSON output is ideal LLM input.
  • Claude / ChatGPT as the planner: paste JSON inventory plus your package.json; the dependency list plus module sizes together let it spot duplicate-purpose libraries the treemap alone hides.
  • Claude Code / Cursor for execution: good at the mechanical items — converting to subpath imports, adding next/dynamic/React.lazy boundaries — with you re-measuring after each.

Verification

  • Every merged item has analyzer output before and after, showing the claimed chunk actually shrank (compressed size, not just raw).
  • First-load JS on the critical route dropped by the summed measured savings — and the number reconciles; unexplained gaps mean something moved rather than left.
  • No behavioral regressions: the risk-column checks ran for each risky swap.
  • The CI size budget exists, is set with small margin, and has been seen to fail on a test branch.

Pitfalls

  • Trusting estimated savings. Model KB estimates are guesses dressed as measurements. They are for ranking order only; the rebuild produces the real number.
  • Optimizing raw instead of compressed. A 200KB raw win that is 12KB gzipped may rank below a smaller raw item that compresses poorly. Compare what ships over the wire.
  • Dynamic-importing everything. Split points add request waterfalls and loading states; below-the-fold heavyweights are good candidates, your button component is not. Each split needs a user-visible rationale.
  • Killing a "duplicate" that isn't. Two major versions of a package usually mean two dependents with incompatible ranges — deduping requires resolving the range conflict, not deleting a node_modules folder.
  • Total-size fixation. Moving admin code out of the critical route is a win even if total build output is unchanged. Measure the route, not the repo.
  • One giant cleanup PR. Unattributable, unreviewable, and unrevertable when one of eight changes breaks Safari. One item, one PR, one measurement.

Restricted-environment variant

Bundle inventories reveal your dependency tree and module structure — usually shareable, but some client engagements class even that as confidential.

  • In-tenant model: full workflow unchanged via Copilot Business / Bedrock / Azure endpoints.
  • Local model: rank-and-explain over a JSON inventory is well within a strong local model's ability; expect weaker knowledge of package-ecosystem alternatives, so lean on it for duplicates and split points, and research replacements yourself.
  • No model: the analyzer plus npm why plus this playbook's checklist (duplicates, same-job libraries, full-library imports, polyfills, split candidates) is a fine manual protocol — the LLM compresses hours into minutes but adds nothing you cannot enumerate.
Warning

Never paste source maps or bundle contents from a client's proprietary app into a public tool — a source map is close to the source code itself. Inventories (module paths and sizes) are the most that should travel, and only where the engagement allows.

Success criteria

  • First-load JS on the target route is under budget with measured attribution for every KB recovered.
  • The team can answer "why did the bundle grow this week?" from CI artifacts in minutes.
  • The size budget has caught at least one would-be regression in CI rather than in Lighthouse after deploy.
  • Bundle review became routine: heavy-dependency questions now appear in PR review before merge, not in investigations after.
This is the free reading view. Open BXUP to track your progress, run the hands-on labs, and prove it with original, exam-pattern assessments.
© Anvi Innovate · BXUP — Be Exponentially Upskilled · BXUP is an independent learning platform, not affiliated with or endorsed by AWS, Microsoft, Google, NVIDIA, IBM, Salesforce, Databricks, Oracle or Anthropic. All trademarks belong to their respective owners. · bxup.in