---
name: react-performance
user-invocable: false
description: Use when React performance optimization including memoization, lazy loading, and virtualization. Use when optimizing React applications.
allowed-tools:
- Bash
- Read
---
# React Performance Optimization
Master react performance optimization for building high-performance, scalable
React applications with industry best practices.
## React.memo and Component Memoization
React.memo prevents unnecessary re-renders by memoizing component output:
```typescript
import { memo } from 'react';
interface Props {
name: string;
onClick: () => void;
}
// Basic memoization
const ExpensiveComponent = memo(
function ExpensiveComponent({ name, onClick }: Props) {
console.log('Rendering ExpensiveComponent');
return ;
});
// Custom comparison function
const CustomMemo = memo(
function Component({ user }: { user: User }) {
return
{user.name}
;
},
(prevProps, nextProps) => {
// Return true if passing nextProps would return the same result as prevProps
return prevProps.user.id === nextProps.user.id;
}
);
// When to use custom comparison
const ProductCard = memo(
function ProductCard({ product }: { product: Product }) {
return (
);
}
```
## React Profiler API for Performance Monitoring
```typescript
import { Profiler, ProfilerOnRenderCallback } from 'react';
const onRenderCallback: ProfilerOnRenderCallback = (
id, // the "id" prop of the Profiler tree that has just committed
phase, // either "mount" (first render) or "update" (re-render)
actualDuration, // time spent rendering the committed update
baseDuration, // estimated time to render the entire subtree without memoization
startTime, // when React began rendering this update
commitTime, // when React committed this update
interactions // the Set of interactions belonging to this update
) => {
console.log(`${id} (${phase}) took ${actualDuration}ms`);
// Send to analytics
if (actualDuration > 100) {
analytics.track('slow-render', {
component: id,
duration: actualDuration,
phase
});
}
};
function App() {
return (
);
}
// Nested profilers for granular monitoring
function Dashboard() {
return (
);
}
```
## Bundle Size Optimization
```typescript
// Use dynamic imports for large libraries
function ChartComponent() {
const [Chart, setChart] = useState(null);
useEffect(() => {
// Only load chart library when needed
import('chart.js').then(module => {
setChart(() => module.Chart);
});
}, []);
if (!Chart) return
);
}
```
## When to Use This Skill
Use react-performance when you need to:
- Optimize slow-rendering components
- Reduce bundle size with code splitting
- Handle large lists with virtualization
- Prevent unnecessary re-renders
- Improve application load time
- Optimize expensive computations
- Build performant React applications
- Debug performance issues
- Implement lazy loading strategies
- Improve Core Web Vitals scores
- Optimize for mobile devices
- Handle real-time data efficiently
## Best Practices
1. **Profile before optimizing** - Use React DevTools Profiler to identify actual
bottlenecks before applying optimizations.
2. **Use React.memo wisely** - Only memoize components that render often with the
same props or have expensive render logic.
3. **Memoize callbacks and values** - Use useCallback for functions passed to
memoized children, useMemo for expensive computations.
4. **Code split by route** - Lazy load route components to reduce initial bundle
size and improve load time.
5. **Virtualize long lists** - Use react-window or react-virtualized for lists
with more than 100 items.
6. **Optimize images** - Lazy load images, use appropriate formats (WebP),
implement progressive loading.
7. **Debounce expensive operations** - Debounce search inputs, API calls, and
other expensive operations.
8. **Split context strategically** - Separate read and write contexts to prevent
unnecessary consumer re-renders.
9. **Monitor bundle size** - Use webpack-bundle-analyzer to identify and remove
large dependencies.
10. **Use concurrent features** - Leverage useTransition and useDeferredValue for
better perceived performance.
## Common Pitfalls
1. **Premature optimization** - Don't optimize without measuring. Profile first,
then optimize bottlenecks.
2. **Overusing memo** - Memoizing everything adds overhead. Only memoize when
there's a measurable benefit.
3. **Wrong dependencies** - Missing dependencies in useMemo/useCallback leads to
stale closures and bugs.
4. **Not measuring impact** - Always measure performance improvements with React
Profiler or browser tools.
5. **Ignoring bundle size** - Importing large libraries for small features
significantly impacts load time.
6. **Memoizing primitives** - useMemo is unnecessary for primitive values or
simple calculations.
7. **Not using key prop** - Missing or incorrect keys in lists cause unnecessary
re-renders and bugs.
8. **Inline function definitions** - Creating functions inline in JSX prevents
React.memo from working effectively.
9. **Not code splitting** - Loading entire app upfront increases initial load
time dramatically.
10. **Forgetting about network** - Optimize data fetching, use pagination,
implement proper caching strategies.
## Resources
- [React Documentation - Performance](https://react.dev/learn/render-and-commit)
- [React DevTools Profiler](https://react.dev/learn/react-developer-tools)
- [Web.dev - React Performance](https://web.dev/react/)
- [React Performance Optimization Tips](https://kentcdodds.com/blog/usememo-and-usecallback)
- [Bundle Size Optimization](https://webpack.js.org/guides/code-splitting/)
- [react-window Documentation](https://github.com/bvaughn/react-window)