Estimated reading time: 7 minutes By: Editorial Team Published: March 8, 2024
Overview
Performance budgets are constraints on page weight, loading time, or Lighthouse scores that the team commits to maintaining. Without them, performance degrades by default: every added dependency, third-party script, and marketing pixel is individually defensible but collectively ruinous.
Key takeaways
- A performance budget is a constraint, not a goal — exceeding it fails the build.
- Budgets should be set from user research and competitor analysis, not wishful thinking.
- Automated enforcement in CI is the only kind that works long-term.
- Budgets must be reviewed and updated as product requirements evolve.
Why budgets degrade without enforcement
Adding 20 KB to a page feels harmless in isolation. Done ten times in a sprint, it doubles the page weight. The mechanism is well-understood: each decision is made locally by the person closest to it, without visibility into the cumulative effect. A budget externalizes that cumulative effect into a shared constraint visible to the whole team.
Setting a realistic budget
A budget that is already violated at launch is worse than no budget — it signals that the constraint is decorative.
Reference points for budget-setting
- Your current state — measure the page before adding a budget; the budget must allow the page to pass today
- Competitor baselines — measure the 50th-percentile performance of 3–5 competitors using WebPageTest; your budget should match or beat them
- User research — 53% of mobile users abandon pages that take longer than 3 seconds to load; align budgets with the connection speeds of your target audience
- Core Web Vitals — Google's LCP, INP, and CLS thresholds are widely accepted baselines and affect search ranking
Recommended starting budgets
| Metric | Target |
|---|---|
| Largest Contentful Paint (LCP) | ≤ 2.5 seconds |
| Interaction to Next Paint (INP) | ≤ 200 ms |
| Cumulative Layout Shift (CLS) | ≤ 0.1 |
| Total page weight | ≤ 500 KB (transferred) |
| JavaScript bundle | ≤ 150 KB (parsed + executed) |
| Third-party scripts | ≤ 2 synchronous, all others deferred |
Adjust based on your product's specific context — a data-heavy dashboard has different constraints than a marketing landing page.
Enforcing budgets in CI
A budget documented in a README is aspirational. A budget enforced in a CI pipeline is a constraint.
Lighthouse CI
Lighthouse CI runs Google Lighthouse audits on every pull request and fails the build when scores fall below defined thresholds.
# .lighthouserc.yml
ci:
collect:
url:
- http://localhost:3000/
assert:
preset: lighthouse:recommended
assertions:
largest-contentful-paint:
- error
- maxNumericValue: 2500
total-byte-weight:
- error
- maxNumericValue: 512000
Bundlesize / size-limit
For JavaScript budgets, tools like size-limit check the final bundle at build time:
// package.json
"size-limit": [
{
"path": "dist/assets/js/main.js",
"limit": "150 kB"
}
]
A failed size check blocks the merge — the developer must either optimize the code or update the budget with explicit justification.
Keeping budgets visible
Automated enforcement handles regressions, but budgets should also be visible in day-to-day work.
Dashboard integration
Add a performance dashboard (Lighthouse CI's dashboard, SpeedCurve, or a self-hosted alternative) to your team's internal tooling. Graphs showing score trends over time make degradation visible before it becomes a problem.
Pull request annotations
Configure CI to post budget results as PR comments. Developers see the performance impact of their changes during review, not after merge.
When to update a budget
A budget is not immutable. Review it when:
- A major new feature requires capabilities that cannot be delivered within the current budget
- The product's target audience changes (new device or network demographics)
- Web standards evolve and what was acceptable is no longer competitive
When a budget is updated, document the reason and the tradeoff. "We increased the JS budget from 150 KB to 200 KB to support the new rich text editor; we offset this by deferring analytics scripts" is a healthy change. "We removed the budget because it kept failing" is not.
Common budget mistakes
- Measuring only in ideal conditions — always measure on throttled connections simulating real users
- Exempting third-party scripts — third-party tags are often the biggest contributors to weight; they must be in scope
- Setting budgets per-page but shipping shared bundles — measure the total loading experience for a first-time visitor, including shared dependencies
- Never reviewing the budget — products change; budgets that don't evolve with them become obstacles
Conclusion
A performance budget that is set realistically, enforced automatically, and reviewed regularly is one of the most effective quality tools available to a web team. The engineering overhead is low; the protection against gradual degradation is high.