| name | react-performance-optimization |
| description | React performance optimization patterns using memoization, code splitting, and efficient rendering strategies. Use when optimizing slow React applications, reducing bundle size, or improving user experience with large datasets. Trigger this skill proactively when user phrasing matches its domain, keywords, or expected workflow outcomes;. Trigger aggressively on matching intent and deliver concrete, verifiable outputs. Prioritize profiling-backed React optimizations: render hotspots, memoization validity, and split strategies. |
React Performance Optimization
Expert guidance for optimizing React application performance through memoization, code splitting, virtualization, and efficient rendering strategies.
When to Use This Skill
- Optimizing slow-rendering React components
- Reducing bundle size for faster initial load times
- Improving responsiveness for large lists or data tables
- Preventing unnecessary re-renders in complex component trees
- Optimizing state management to reduce render cascades
- Improving perceived performance with code splitting
- Debugging performance issues with React DevTools Profiler
Core Concepts
React Rendering Optimization
React re-renders components when props or state change. Unnecessary re-renders waste CPU cycles and degrade user experience. Key optimization techniques:
- Memoization: Cache component renders and computed values
- Code splitting: Load code on demand for faster initial loads
- Virtualization: Render only visible list items
- State optimization: Structure state to minimize render cascades
When to Optimize
- Profile first: Use React DevTools Profiler to identify actual bottlenecks
- Measure impact: Verify optimization improves performance
- Avoid premature optimization: Don't optimize fast components
Quick Reference
Load detailed patterns and examples as needed:
| Topic | Reference File |
|---|
| React.memo, useMemo, useCallback patterns | .agents/skills/react-performance-optimization/references/memoization.md |
| Code splitting with lazy/Suspense, bundle optimization | .agents/skills/react-performance-optimization/references/code-splitting.md |
| Virtualization for large lists (react-window) | .agents/skills/react-performance-optimization/references/virtualization.md |
| State management strategies, context splitting | .agents/skills/react-performance-optimization/references/state-management.md |
| useTransition, useDeferredValue (React 18+) | .agents/skills/react-performance-optimization/references/concurrent-features.md |
| React DevTools Profiler, performance monitoring | .agents/skills/react-performance-optimization/references/profiling-debugging.md |
| Common pitfalls and anti-patterns | .agents/skills/react-performance-optimization/references/common-pitfalls.md |
Optimization Workflow
1. Identify Bottlenecks
Look for:
- Components with yellow/red bars (slow renders)
- Unnecessary renders (same props/state)
- Expensive computations on every render
2. Apply Targeted Optimizations
For unnecessary re-renders:
- Wrap component with
React.memo
- Use
useCallback for stable function references
- Check for inline objects/arrays in props
For expensive computations:
- Use
useMemo to cache results
- Move calculations outside render when possible
For large lists:
- Implement virtualization with react-window
- Ensure proper unique keys (not index)
For slow initial load:
- Add code splitting with
React.lazy
- Analyze bundle size with webpack-bundle-analyzer
- Use dynamic imports for heavy dependencies
3. Verify Improvements
Common Patterns
Memoize Expensive Components
import { memo } from 'react'
const ExpensiveList = memo(({ items, onItemClick }) => {
return items.map(item => (
<Item key={item.id} data={item} onClick={onItemClick} />
))
})
Cache Computed Values
import { useMemo } from 'react'
function DataTable({ items, filters }) {
const filteredItems = useMemo(() => {
return items.filter(item => filters.includes(item.category))
}, [items, filters])
return <Table data={filteredItems} />
}
Stable Function References
import { useCallback } from 'react'
function Parent() {
const handleClick = useCallback(id => {
console.log('Clicked:', id)
}, [])
return <MemoizedChild onClick={handleClick} />
}
Code Split Routes
import { lazy, Suspense } from 'react'
const Dashboard = lazy(() => import('./Dashboard'))
const Reports = lazy(() => import('./Reports'))
function App() {
return (
<Suspense fallback={<Loading />}>
<Routes>
<Route path='/' element={<Dashboard />} />
<Route path='/reports' element={<Reports />} />
</Routes>
</Suspense>
)
}
Virtualize Large Lists
import { FixedSizeList } from 'react-window'
const Row = ({ index, style, data }) => (
<div style={style}>{data[index].name}</div>
)
function VirtualList({ items }) {
return (
<FixedSizeList
height={600}
itemCount={items.length}
itemSize={80}
width='100%'
itemData={items}
>
{Row}
</FixedSizeList>
)
}
Common Mistakes
- Over-memoization: Don't memoize simple, fast components (adds overhead)
- Inline objects/arrays: New references break memoization (
config={{ theme: 'dark' }})
- Missing dependencies: Stale closures in useCallback/useMemo
- Index as key: Breaks reconciliation when list order changes
- Single large context: Causes widespread re-renders on any update
- No profiling: Optimizing without measuring wastes time
Performance Checklist
Before optimizing:
Optimization targets:
After optimizing:
Resources