Skip to content

build: add bundle-size analysis tooling + baseline report + 500 kB gate#31

Closed
adm01-debug wants to merge 1 commit into
mainfrom
claude/bundle-analysis
Closed

build: add bundle-size analysis tooling + baseline report + 500 kB gate#31
adm01-debug wants to merge 1 commit into
mainfrom
claude/bundle-analysis

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

Summary

Adds bundle-size analysis tooling, a baseline report, an optimization plan, and a CI-ready 500 kB gzip gate.

Why

The build is currently healthy — no chunk exceeds 500 kB gzip — but there was no tooling to verify that or to detect regressions. rollup-plugin-visualizer is wired in vite.config.ts but its mode === 'production' conditional doesn't reliably emit dist/stats.html on the current Vite version, leaving no post-build view of the bundle.

Current baseline

Total: 2.97 MB gzip / 13.6 MB raw across 294 chunks
Largest chunk: export-vendor (182 kB gzip / 608 kB raw)
> 500 kB gzip: 0 chunks ✅
> 250 kB gzip: 0 chunks ✅

What's added

scripts/bundle-analysis.mjs

Standalone analyzer that walks dist/assets/*.js, computes raw + gzip sizes, buckets chunks by category (vendor:*, page:admin, page:other, hook, ui:overlay, app:entry, lazy:chunk), and emits:

  • Human table to stdout (default)
  • JSON to stdout (--json)
  • Markdown to docs/BUNDLE_REPORT.md (--md)
  • Exit 1 if any chunk > 500 kB gzip (--check) — for CI gate

npm scripts

"build:analyze":       "vite build && node scripts/bundle-analysis.mjs",
"build:analyze:md":    "vite build && node scripts/bundle-analysis.mjs --md",
"build:analyze:check": "vite build && node scripts/bundle-analysis.mjs --check",

docs/BUNDLE_ANALYSIS.md + docs/BUNDLE_REPORT.md

  • BUNDLE_ANALYSIS.md — narrative: current state, top offender table, prioritized optimization plan (medium: lucide-react tree-shaking ≈ 80–100 kB gzip savings; medium: split AdminConexoesPage explain-mode), CI workflow snippet
  • BUNDLE_REPORT.md — auto-generated machine output (top 15 chunks, by-category breakdown, flagged offenders)

CI gate (suggested follow-up)

- name: Bundle size budget
  run: npm run build:analyze:check

Hard error at 500 kB gzip rather than soft warn — that's the threshold where mobile TTI starts to degrade meaningfully.

Test plan

  • node scripts/bundle-analysis.mjs — works on current dist/
  • node scripts/bundle-analysis.mjs --md — writes docs/BUNDLE_REPORT.md
  • node scripts/bundle-analysis.mjs --check — exits 0 (no offenders today)
  • npm run build:analyze — full pipeline

https://claude.ai/code/session_01KWeDG


Generated by Claude Code

The current build is healthy (no chunk > 500 kB gzip) but there was
no tooling to verify that or detect regressions. The 'rollup-plugin-
visualizer' is wired in vite.config.ts but its 'mode === production'
conditional doesn't reliably emit dist/stats.html on the current Vite
version, leaving no post-build view of the bundle.

## What's added

### scripts/bundle-analysis.mjs
Standalone analyzer that walks dist/assets/.js, computes raw + gzip
sizes, buckets chunks by category (vendor:*, page:admin, page:other,
hook, ui:overlay, app:entry, lazy:chunk), and emits:
  - Human table to stdout (default)
  - JSON to stdout (--json)
  - Markdown to docs/BUNDLE_REPORT.md (--md)
  - Exit 1 if any chunk > 500 kB gzip (--check) — for CI gate

### npm scripts
  build:analyze       → vite build && analyze
  build:analyze:md    → vite build && write report to docs/BUNDLE_REPORT.md
  build:analyze:check → vite build && fail if > 500 kB gzip chunk exists

### docs/BUNDLE_ANALYSIS.md
Narrative analysis: current baseline (~2.97 MB gzip across 294 chunks,
no offenders), top offender table with raw + gzip sizes, prioritized
optimization plan (medium: lucide-react tree-shaking saves 80-100 kB
gzip; medium: split AdminConexoesPage explain-mode), and a
suggested CI workflow snippet to enforce the 500 kB gate.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bc22ae2e-441b-4837-a596-7c36403eeaad

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/bundle-analysis

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Owner Author

Update on the lucide-react tree-shaking suggestion (§ Optimization opportunities, 🟡 Medium)

I tested the suggested codemod (rewriting import { X } from 'lucide-react' to import X from 'lucide-react/dist/esm/icons/<x>') on a branch off main:

  • 1568 source files scanned
  • 880 import blocks rewritten across 869 files
  • 4375 icon specifiers converted

Result: zero size change. icons-vendor chunk stayed at exactly 680171 bytes / 120.96 kB gzip before and after.

Why it's a no-op

lucide-react@0.309.0 declares "sideEffects": false in its package.json, which is the canonical signal to Rollup/Vite that all named exports from the barrel can be tree-shaken individually. The 285 icons our app actually imports are exactly what ends up in the bundle, regardless of whether they come via import { Foo } from 'lucide-react' or import Foo from 'lucide-react/dist/esm/icons/foo'.

Implication for docs/BUNDLE_ANALYSIS.md

The 80–100 kB savings claim in the doc isn't reachable on this lucide version. The icons-vendor chunk size is already at the tree-shaken minimum — it's 285 icons × ~2 kB each (raw) plus the runtime helper. The only ways to shrink it further:

  1. Use fewer icons (product policy, not technical optimization)
  2. Bump lucide-react if a future version exposes a smaller per-icon helper
  3. Switch to a different icon library (heroicons, radix-icons, etc.)

I'd suggest editing the relevant section of the doc on this branch before merging — replacing the "Medium savings" claim with the no-op finding and the three actual options above. I won't push that change here without your input since it's your PR; happy to do a follow-up PR if preferred.

The 869-file refactor was verified locally (tsc --noEmit and full vite build both passed) but is not being shipped because the trade-off (massive diff, no measurable benefit) doesn't pencil out.


Generated by Claude Code

@adm01-debug adm01-debug deleted the claude/bundle-analysis branch May 9, 2026 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants