A performance budget is a numeric limit on metrics that matter — page weight, JavaScript bundle size.
A performance budget is a numeric ceiling on measurable performance characteristics — total JavaScript bytes, image weight, Largest Contentful Paint (LCP), Interaction to Next Paint (INP), Time to First Byte (TTFB) — that CI enforces automatically. Without a budget, performance degrades one PR at a time: each individual change adds 5KB, and six months later the site is 500KB heavier with no single change to blame. Budgets make performance a first-class engineering constraint alongside test coverage and type-checking.
Two categories of metric. (a) Resource metrics — total JS bytes, CSS bytes, image bytes, third-party request count. These are what you can control at build time. (b) Experience metrics — the Core Web Vitals: LCP (under 2.5s), INP (under 200ms), CLS (under 0.1). These are what users actually experience and what Google ranks on. Budget both; resource budgets prevent regressions before deploy, experience budgets catch what resource budgets miss (a small script that blocks the main thread hurts INP without moving any byte count).
Start from where you are, tighten from there. Measure current values across your top pages, set the budget slightly stricter than the current p75 — enough to prevent regression but achievable. Common starting points for a SaaS marketing site: 200KB JS gzipped, 500KB total page weight, LCP under 2.5s on 4G. For a heavy web app: 400KB initial JS, 1MB total, LCP under 3s. Aspirational budgets you constantly miss produce alert fatigue; budgets aligned with reality produce discipline. Tighten quarterly as you optimize.
Tooling: Lighthouse CI (Google) runs Lighthouse on every PR, compares against budgets defined in lighthouserc.js, comments on the PR with pass/fail. Bundle-analyzer plugins (webpack-bundle-analyzer, size-limit, bundlesize) enforce byte budgets per bundle. Both should block merge on regression above threshold, not just warn. Warnings are ignored; blocking is respected. For experience metrics that vary run-to-run, take the median of 3-5 runs to reduce false positives.
CI runs synthetic tests on a controlled machine — useful for regression detection but not representative of real user experience across devices, networks, and geographies. Complement with RUM tools (Vercel Analytics, SpeedCurve, DataDog RUM, or the free Chrome UX Report) that measure actual field metrics from actual users. When synthetic Lighthouse says LCP is 1.8s but RUM says field p75 LCP is 4.2s, the RUM number is the one users experience. Set experience-metric budgets against RUM p75, not synthetic.
Distributed ownership fails — 'everyone owns performance' means nobody does. Effective model: a small performance-champions group (2-4 engineers) owns the budgets, the tooling, and the escalation for regressions; every team owns their own budget compliance. When a budget is exceeded, the team that broke it fixes it, not the performance group. The performance group's job is enabling and reviewing, not fixing everyone else's regressions. Without this structure, performance work becomes janitorial and gets deprioritized.
Investor directory · Fundraising library · Articles A–Z · Company funding database