Learn how to define a Performance Budget, set Core Web Vitals targets, and automate regression testing using Lighthouse CI to keep your React app fast.
Previously in this course, we explored Profiling with React DevTools to understand how and why components re-render. While profiling helps us fix specific bottlenecks, it is a manual, reactive process. To scale performance, we must move from reactive debugging to proactive governance.
This lesson introduces the Performance Budget—a set of quantitative constraints that define the acceptable limits for your application's performance. Without these, performance is just a "nice to have" that inevitably degrades as features accumulate.
A Performance Budget isn't just about total bundle size; it’s about user experience. We use Core Web Vitals as our primary North Star metrics because they correlate directly with real-world user satisfaction.
For our project, we will adopt the "Good" thresholds defined by Google:
| Metric | Target (Desktop/Mobile) | What it represents |
|---|---|---|
| LCP | < 2.5s | Loading performance |
| INP | < 200ms | Interactivity |
| CLS | < 0.1 | Visual stability |
If you haven't yet implemented tracking, consider Core Web Vitals tracking: Implementing Reliable RUM with Beacon API to validate these targets against real user data rather than just synthetic lab environments.
Before we enforce limits, we need to know where we stand. Run an initial audit using the Lighthouse CLI to generate a baseline.
Bash# Install Lighthouse npm install -g lighthouse # Run a baseline audit on your local dev server lighthouse http://localhost:3000 --view --output-path=./performance-baseline.html
Open the generated performance-baseline.html. Note your scores. If your LCP or CLS are failing, do not set the budget to your current (bad) score. Set it to the "Good" threshold. This forces you to optimize immediately to pass the build, rather than accepting poor performance as the new normal.
To prevent future regressions, we integrate Performance Budgets: Automating Regression Testing with Lighthouse CI. This turns your performance budget into a "fail-fast" gate in your CI/CD pipeline.
Install the CLI:
npm install --save-dev @lhci/cli
Create lighthouserc.js in your root:
JAVASCRIPTmodule.exports = { ci: { assert: { preset: CE9178">'lighthouse:recommended', assertions: { CE9178">'largest-contentful-paint': [CE9178">'error', { minScore: 0.9 }], CE9178">'cumulative-layout-shift': [CE9178">'error', { minScore: 0.9 }], CE9178">'interactive': [CE9178">'error', { minScore: 0.9 }], CE9178">'total-byte-weight': [CE9178">'error', { maxNumericValue: 500000 }], // 500KB limit }, }, }, };
Add to your CI pipeline:
In your GitHub Actions or GitLab CI file, add a step to run lhci autorun. This will spin up your app, run Lighthouse, and fail the build if your budget is exceeded.
lighthouserc.js to set a total-byte-weight budget. Start with a value 20% higher than your current bundle size.App.js. Run your CI script locally to confirm that the build fails.We've established that performance is a feature, not an afterthought. By setting Core Web Vitals targets, establishing a baseline, and using Lighthouse CI to enforce budgets, we ensure that our performance gains aren't eroded by future code changes.
Up next: We will dive into Strategic use of React.memo to begin optimizing our component tree based on the bottlenecks identified in our initial profiling.
Master Code Splitting in React using dynamic imports and Suspense. Learn how to architect your app for faster initial loads and smaller bundle sizes.
Read moreLearn to master Cache Invalidation in React. Configure precise keys, perform manual mutations, and handle stale-while-revalidate patterns for robust apps.
Offloading Tasks with Web Workers
Advanced Error Boundaries
Monitoring Production Performance
Final Project Audit & Optimization
Advanced Hook Patterns
Managing Global State with Zustand/Redux
Testing Performance-Critical Components
Static Site Generation (SSG) Patterns
Internationalization (i18n) Architecture
Accessibility (a11y) in Advanced Components
Managing Third-Party Integrations
Advanced Form Handling
Using Portals for UI Overlays
Implementing Virtualized Lists
Building Design System Primitives
Managing Large-Scale Data Fetching
Micro-Frontends with React
Security Best Practices in React
Advanced Ref Usage
Memoization Pitfalls
Mastering React Patterns for Scalability
Advanced TypeScript with React