Frontend Performance Budgets That Actually Stick
Most teams say they care about speed. Few teams define what "fast enough" means in numbers. A performance budget fixes that: hard limits on JavaScript, CSS, images, and key metrics - so every feature ships with a speed cost attached.
Why Budgets Beat Vague Goals
"Make it faster" is not actionable. "Keep LCP under 2.5s on a mid-tier phone over 4G" is. Budgets work because they:
- Force trade-offs before merge, not after a traffic spike
- Give designers and PMs a shared language with engineers
- Catch regressions in CI instead of in Search Console three months later
If you already track Core Web Vitals, budgets are the missing control loop.
Start With Three Numbers
Don't budget everything on day one. Pick three limits that match how users feel your site:
- JavaScript transfer size - total JS downloaded on first load (gzipped)
- Largest Contentful Paint (LCP) - lab + field
- Image weight above the fold - hero + critical assets
Example starting points for a marketing or content site:
JS (gzipped): <= 150 KB
LCP (field p75): <= 2.5 s
Hero image: <= 200 KB
Product apps can raise the JS budget - but raise it deliberately, with a documented reason.
Measure Lab and Field
Lab tools (Lighthouse, WebPageTest) catch regressions fast. Field data (CrUX, RUM) shows real users. Use both:
- CI / PR checks - Lighthouse CI or bundlesize against the JS/CSS budget
- Weekly review - Search Console Core Web Vitals + your RUM dashboard
- Release gate - block deploys that blow the budget without an explicit exception
A green Lighthouse score with a red CrUX report usually means your lab device is too optimistic. Test on a throttled mobile profile.
Cut Weight Where It Counts
When you blow the budget, fix the expensive parts first:
JavaScript
- Prefer native HTML/CSS before another framework island
- Code-split routes; don't ship admin UI to anonymous visitors
- Audit third-party scripts - analytics, chat widgets, and tag managers add up fast
- Tree-shake and drop unused polyfills
Images
- Serve modern formats (AVIF/WebP) with sensible fallbacks
- Always set width/height (or aspect-ratio) to avoid CLS
- Lazy-load below-the-fold images; preload only the true LCP image
- Crop and compress at the source - don't ship a 3000px photo into a 600px slot
CSS
- Avoid huge utility dumps on pages that use 5% of the classes
- Inline critical CSS sparingly; defer the rest
- Watch font files - subset and
font-display: swap
Make Budgets Visible in the Workflow
Budgets die when only one engineer remembers them. Wire them into daily work:
{
"budgets": [
{
"path": "/*.js",
"resourceSizes": [{ "resourceType": "script", "budget": 150 }]
}
]
}
Lighthouse CI can fail the build when that budget is exceeded. Pair it with a short ADR or wiki note: what the budget is, why it exists, and who can approve exceptions.
When to Raise the Budget
Raising a budget is fine. Quietly ignoring it is not. Treat an increase like an API change:
- Document the feature that needs the weight
- Note the expected user impact
- Set a follow-up date to revisit (remove experiment scripts, split a mega-bundle)
Temporary exceptions that never expire become the new normal.
Wrapping Up
Frontend performance budgets turn speed from a hope into a shipping constraint. Start with JS weight, LCP, and hero images. Enforce in CI, review field data weekly, and raise limits only with a paper trail.
Need help auditing a slow frontend or setting budgets for a redesign? Contact NekoCoding for a performance review.