← Workflows

阅读中文版本

Frontend Bundle Slimming Cycle Workflow

Set a byte budget per route, measure the shipped bundle continuously, remove the biggest offenders, and hold the line with CI gates.

intermediate~30 minperformance-tuningfrontendbundling

Objective

Reduce and then hold frontend payload size through per-route budgets, offender analysis, and budget-enforcing CI checks.

Environment

  • Bundle analysis tooling in the build (analyzer plugin)
  • CI able to fail on size thresholds
  • A budget policy agreed with product and design

Steps

1. Set budgets per route, not per app

Define gzip byte budgets per route (landing, app, admin) reflecting their value and traffic, rather than one global number.

Expected state: A budget table exists per route with current size and target.

2. Measure what actually ships

Generate the bundle report in CI for every build, tracking per-route gzip size and module attribution (what each dependency costs).

Expected state: Every build produces a size report with per-module bytes.

3. Attack the biggest offenders

From the report, remove the top costs: duplicate libraries, full-package imports where submodules suffice, eagerly-bundled rarely-used features.

Expected state: The offender list shrinks with named removals and their byte savings.

4. Move what remains heavy to lazy

Code-split heavy-but-rare paths (admin, editors, charts) behind dynamic imports with prefetched weights for likely use.

Expected state: Initial route payloads drop while heavy paths load on demand.

5. Enforce with CI gates

Fail the build when any route exceeds its budget, with a documented override for accepted exceptions carrying an expiry.

Expected state: A PR that adds 40KB to a budgeted route fails CI automatically.

Expected outcome

Route payloads within declared budgets, offenders removed with evidence, lazy boundaries in place, and CI holding the line against regression.

Verification

The size report history shows monotone reduction to budget; an intentional +40KB change fails CI and requires an explicit waiver.

Bytes are a budget line item, not an accident

Bundle size grows by a few kilobytes per feature until the product loads like wet cement. Per-route budgets make size a visible decision, the analyzer attributes every byte, and the CI gate converts the budget from aspiration to enforcement.

route budgets (gzip):
  /            130KB   current: 214KB  VIOLATION
  /app         260KB   current: 241KB  ok
  /admin       180KB   current: 412KB  VIOLATION

offenders (analyzer, route /):
  moment + locale data          68KB -> date-fns (12KB)
  lodash full                   24KB -> lodash-es tree-shaken (4KB)
  chart lib (eager)             51KB -> lazy on chart open

offenders (/admin):
  two editor libs bundled       -> keep one, lazy other

after: / = 122KB (under budget), /admin = 171KB
CI: route budget check FAILS any +40KB regression

Route budgets localize the argument

A global 150-kilobyte limit punishes the admin console for the landing page’s promise and gets waived into uselessness. Per-route budgets sized by traffic and value let each surface negotiate its own number, which is why they survive contact with reality.

The waiver must be visible and mortal

Budget gates without a waiver path get disabled the week before a launch. The durable pattern is the CI failure plus a documented waiver: reason, owner, expiry. Size debt becomes explicit and reviewable instead of an accumulating silent leak.