π React Profiler vs Lighthouse: Performance Tools Every Developer Needs to Know
Performance is critical for any web application. But when you notice your app is slow, which tool do you use to find the problem?
In this article we'll compare two of the most powerful performance diagnosis tools: React Profiler and Lighthouse. We'll understand when to use each one and how to work with them together.
π§ͺ React Profiler: Internal Component Analysis
The React Profiler is a built-in React tool that measures your component performance in real time.
What it does
The React Profiler tracks:
- β±οΈ Render time - How long each component takes to render
- π Re-renders - How many times each component was rendered
- π¦ Component size - Relative size in the component tree
- π― Commits - Each DOM update and when it occurred
- π Component relationships - How re-renders cascade
How to Use
The React Profiler is available in React Developer Tools (Chrome extension):
- Install React Developer Tools
- Open the Profiler tab
- Click Record (red circle button)
- Interact with your app (click buttons, change state, etc.)
- Click Record again to stop
- Analyze the collected data
Real Example: Identifying Unnecessary Renders
// β Component that re-renders unnecessarily
function UserList({ users, onSelect }) {
console.log('UserList rendered');
return (
<div>
{users.map(user => (
<UserCard
key={user.id}
user={user}
onSelect={onSelect}
/>
))}
</div>
);
}
function UserCard({ user, onSelect }) {
console.log(`UserCard rendered: ${user.id}`);
return (
<div onClick={() => onSelect(user.id)}>
{user.name}
</div>
);
}
With the React Profiler you'll see:
- UserList renders every time state changes
- All UserCard components render even if the specific user didn't change
- Total time increases exponentially with the number of users
Solution with memo()
// β
Optimized with React.memo
const UserCard = React.memo(function UserCard({ user, onSelect }) {
console.log(`UserCard rendered: ${user.id}`);
return (
<div onClick={() => onSelect(user.id)}>
{user.name}
</div>
);
});
function UserList({ users, onSelect }) {
// memoize callback to prevent UserCard re-renders
const handleSelect = useCallback((userId) => {
onSelect(userId);
}, [onSelect]);
return (
<div>
{users.map(user => (
<UserCard
key={user.id}
user={user}
onSelect={handleSelect}
/>
))}
</div>
);
}
Now with the React Profiler you'll see:
- β UserList renders normally
- β Only UserCard that changed renders
- β Total time drastically reduced
ποΈ Lighthouse: Complete Web Audit
Lighthouse is a tool from Google Chrome that does a complete audit of your web application.
What it does
Lighthouse measures:
- β‘ Performance - Overall page speed
- βΏ Accessibility - Accessibility for users with disabilities
- π± Best Practices - Compliance with recommended practices
- π Security - Security vulnerabilities
- π SEO - Search engine optimization
How to Use
- Open Chrome DevTools (F12 or Cmd+Option+I)
- Go to the Lighthouse tab
- Select what you want to audit (can be Mobile or Desktop)
- Click Analyze page load
- Wait for the complete report
Key Metrics
Core Web Vitals
Lighthouse focuses on three critical metrics:
-
LCP (Largest Contentful Paint)
- When the largest visible element appears
- Target:
< 2.5s
-
FID (First Input Delay)
- How long the page takes to respond to user input
- Target:
< 100ms
-
CLS (Cumulative Layout Shift)
- How much the layout moves while the page loads
- Target:
< 0.1
Sample Report
A typical Lighthouse report shows:
Performance: 85/100
β Largest Contentful Paint: 1.8s
β First Input Delay: 45ms
β Cumulative Layout Shift: 0.05
β Unused JavaScript: 245kb
β Unused CSS: 89kb
β Images not sized correctly: 3 warnings
π― Comparison: React Profiler vs Lighthouse
| Aspect | React Profiler | Lighthouse |
|---|---|---|
| Focus | React components | Entire page |
| Cause | Why does it render? | How to optimize? |
| Metric | Render time | Core Web Vitals |
| Access | Inside app (DevTools) | During audit time |
| Granularity | Individual component | Complete page |
| Use Cases | Unnecessary renders | Overall performance |
| Interactivity | Analyzes interactions | Simulates loading |
| Report | Visual in real-time | Detailed scorecard |
π Practical Workflow: Optimizing with Both
STEP 1: Start with Lighthouse
Do a general audit:
# Via CLI (more consistent)
npm install -g @lhci/cli@latest lighthouse
lighthouse https://your-site.com --view
Look for:
- Low performance score
- Bad Core Web Vitals
- Unused files
- Large images
STEP 2: Use React Profiler to Investigate
If Lighthouse pointed out "Unused JavaScript" or "Slow rendering":
- Open React Profiler
- Record a common interaction (scroll, button click)
- Look for:
- Renders that take too long
- Re-renders in cascade
- Components that render for no reason
STEP 3: Implement Optimizations
Based on what you found:
// β Problem: Function defined on each render
function ProductCard({ product, onAddCart }) {
const handleClick = () => {
onAddCart(product.id);
};
return (
<button onClick={handleClick}>
Add to cart
</button>
);
}
// β
Solution: Memoize the function
function ProductCard({ product, onAddCart }) {
const handleClick = useCallback(() => {
onAddCart(product.id);
}, [product.id, onAddCart]);
return (
<button onClick={handleClick}>
Add to cart
</button>
);
}
// β
Solution 2: Memoize the entire component
export const MemoizedProductCard = React.memo(ProductCard);
STEP 4: Validate with Lighthouse Again
Run Lighthouse again to confirm improvements:
lighthouse https://your-site.com --view
You should see:
- Performance score increase
- Core Web Vitals improve
- "Unused JavaScript" decrease
π Practical React Profiler Metrics
Understanding the Graph
When you record an interaction, the Profiler shows:
Commit 1: 234ms
ββ UserList: 45ms (rendered)
ββ UserCard: 12ms (rendered)
ββ UserCard: 11ms (rendered)
ββ UserCard: 10ms (rendered)
Commit 2: 89ms
ββ UserList: 0ms (not rendered)
ββ UserCard: 2ms (rendered - changed!)
ββ UserCard: 0ms (not rendered)
ββ UserCard: 0ms (not rendered)
Colors in Profiler:
- π© Light green - Fast render (
< 5ms) - π¨ Yellow - Medium render (
5-20ms) - π₯ Red - Slow render (
> 20ms)
π Optimization Checklist
After finding issues with these tools:
React Profiler (Internal Optimizations)
- Use
React.memo()for components receiving many props - Use
useCallback()for functions passed as props - Use
useMemo()for expensive object/array calculations - Consider state colocation (move state near where it's used)
- Split large components into smaller ones
Lighthouse (General Optimizations)
- Minimize unused JavaScript
- Optimize images (use WebP, lazy load)
- Implement code splitting
- Use CDN for static assets
- Implement service workers for caching
- Improve Core Web Vitals
π‘ Real Cases
Case 1: Slow E-commerce
Discovered with Lighthouse:
- Performance score: 42/100
- Slow LCP (4.2s)
Investigated with React Profiler:
- ProductCard renders 500 times with same data
- useCallback missing in filter
Solution:
// Add useCallback to filter
const handleFilter = useCallback((category) => {
setFilteredProducts(
products.filter(p => p.category === category)
);
}, [products]);
Result: Performance score: 87/100, LCP: 1.8s
Case 2: Dashboard with Many Charts
Discovered with Lighthouse:
- Performance score: 55/100
- Unused JavaScript: 620kb
Investigated with React Profiler:
- Each chart renders even when data didn't change
- All chart libraries loaded even with only 2 in use
Solution:
// Code splitting chart libraries
const LineChart = lazy(() => import('./charts/LineChart'));
const BarChart = lazy(() => import('./charts/BarChart'));
// Memoize charts
const MemoChart = React.memo(Chart);
Result: Performance score: 91/100, Unused JS: 120kb
π Conclusion
Use React Profiler when:
- β You want to understand why the component renders
- β Investigate cascading re-renders
- β Optimize unnecessary re-renders
- β Debug React-specific issues
Use Lighthouse when:
- β Do a general performance audit
- β Measure Core Web Vitals
- β Check accessibility and SEO
- β Validate implemented improvements
The ideal approach:
- Start with Lighthouse to identify the general problem
- Use React Profiler to investigate specific causes
- Implement optimizations
- Validate with Lighthouse again
Together, these tools form a powerful duo for mastering your React application's performance.
π Resources
- React DevTools
- Lighthouse Documentation
- Core Web Vitals Guide
- React Profiler API
- Web.dev Performance Course
Which tool do you use the most? React Profiler or Lighthouse? Leave a comment! π