Skip to main content
February 18, 20262 min read

Setting a Performance Budget for App Router Projects

A practical way to keep Core Web Vitals healthy by setting explicit performance budgets for assets, routes, and interactions.

PerformancePerformanceCore Web VitalsNext.js

Performance budgets make tradeoffs visible

Without explicit limits, performance work is easy to postpone. A budget turns abstract goals into guardrails teams can use during implementation and review.

Example budget targets for a portfolio/blog:

  • JavaScript per route under 180 KB (compressed)
  • Largest contentful paint under 2.5s on mobile
  • Cumulative layout shift under 0.1

Route-level priorities

Not every route has the same performance profile. For this type of site:

  • Home and blog listing must feel instant
  • Blog detail should prioritize readable text and stable layout
  • Project detail can load richer media progressively

This route-level thinking prevents over-optimizing low-impact pages while neglecting high-traffic ones.

Use images and fonts intentionally

Two common improvements with minimal effort:

  • Serve project previews through next/image
  • Avoid unnecessary external font requests

This keeps image payloads aligned with viewport size and reduces wasted bytes.

Defer non-critical client work

If a component does not need immediate interactivity, keep it server-rendered. Client-only wrappers should be limited to features that truly need browser APIs.

For content pages, this usually means:

  • Render article content on the server
  • Use small client components for progressive enhancements (for example, active TOC highlighting)

Measure continuously

The budget is only useful if measurements happen often. Run Lighthouse locally before merging major UI changes and track trends across releases.

Teams that measure continuously rarely need large rescue refactors later.

Closing thoughts

Performance is product quality. A small, clear budget plus route-aware implementation choices can keep your app fast while still allowing iteration.

Treat budgets as living constraints, update them when your product changes, and keep them visible in pull request discussions.