react-performance
/react-performance
React performance optimization techniques and best practices. Covers memoization, virtualization, code splitting, profiling, React DevTools, bundle optimization, and avoiding common performance pitfalls. USE WHEN: user mentions "React performance", "slow React app", "memoization", "virtualization", "code splitting", "lazy loading", "bundle size", asks about "optimizing React", "React DevTools Profiler", "preventing re-renders" DO NOT USE FOR: React 19 Compiler - use `react-19` skill instead, basic React concepts - use `react` skill instead, testing performance - use `react-testing` skill inste
- Author
- claude-dev-suite ↗
- Repository
- claude-dev-suite ↗
- Licence
- MIT
- Last repository change
- 21.10.2026
Assessment and security
- Files in this package
- 2
- Scripts
- 0
- HTML comments
- 0
- URLs in SKILL.md
- 2
No signals detected. Repository changed on 21.10.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
What it does and when to use it
React performance optimization techniques and best practices. Covers memoization, virtualization, code splitting, profiling, React DevTools, bundle optimization, and avoiding common performance pitfalls. USE WHEN: user mentions "React performance", "slow React app", "memoization", "virtualization", "code splitting", "lazy loading", "bundle size", asks about "optimizing React", "React DevTools Profiler", "preventing re-renders" DO NOT USE FOR: React 19 Compiler - use `react-19` skill instead, basic React concepts - use `react` skill instead, testing performance - use `react-testing` skill inste
Triggers from the description
Original author description
React performance optimization techniques and best practices. Covers memoization, virtualization, code splitting, profiling, React DevTools, bundle optimization, and avoiding common performance pitfalls. USE WHEN: user mentions "React performance", "slow React app", "memoization", "virtualization", "code splitting", "lazy loading", "bundle size", asks about "optimizing React", "React DevTools Profiler", "preventing re-renders" DO NOT USE FOR: React 19 Compiler - use `react-19` skill instead, basic React concepts - use `react` skill instead, testing performance - use `react-testing` skill inste
How it works
- Memoization
- Virtualization
- Code Splitting
- Avoiding Unnecessary Re-renders
- State Management Optimization
- Common Pitfalls
- Best Practices
- When NOT to Use This Skill
- Anti-Patterns
- Quick Troubleshooting
SKILL.md preview
---
name: react-performance
description: |
React performance optimization techniques and best practices. Covers
memoization, virtualization, code splitting, profiling, React DevTools,
bundle optimization, and avoiding common performance pitfalls.
USE WHEN: user mentions "React performance", "slow React app", "memoization", "virtualization",
"code splitting", "lazy loading", "bundle size", asks about "optimizing React",
"React DevTools Profiler", "preventing re-renders"
DO NOT USE FOR: React 19 Compiler - use `react-19` skill instead,
basic React concepts - use `react` skill instead,
testing performance - use `react-testing` skill instead
allowed-tools: Read, Grep, Glob, Write, Edit
---
# React Performance
> **Deep Knowledge**: Use `mcp__documentation__fetch_docs` with technology: `react` topic: `performance` for comprehensive documentation on React performance optimization and profiling techniques.
> **Full Reference**: See [advanced.md](advanced.md) for Profiling with React DevTools, Bundle Optimization, Image Optimization, and Web Workers.
## Memoization
### React.memo
Prevents re-renders when props haven't changed:
```tsx
// Only re-renders when props change (shallow comparison)
const ExpensiveComponent = memo(function ExpensiveComponent({
data,
onItemClick,
}: Props) {
return (
<ul>
{data.map(item => (
<li key={item.id} onClick={() => onItemClick(item.id)}>
{item.name}
</li>
))}
</ul>
);
});
// With custom comparison
const OptimizedComponent = memo(
function OptimizedComponent({ user }: Props) {
return <div>{user.name}</div>;
},
(prevProps, nextProps) => prevProps.user.id === nextProps.user.id
);
```
### When to Use memo
```tsx
// ✅ Good: Expensive component with stable parent
const ExpensiveList = memo(function ExpensiveList({ items }: { items: Item[] }) {
return items.map(item => <ExpensiveItem key={item.id} item={item} />);
});
// ❌ Bad: Simple component, memo overhead not worth it
const SimpleText = memo(function SimpleText({ text }: { text: string }) {
return <span>{text}</span>;
});
// ❌ Bad: Props always change anyway
function Parent() {
// New object on every render - memo is useless!
return <MemoizedChild data={{ value: 1 }} />;
}
```
### useMemo
Memoize expensive calculations:
```tsx
function ProductList({ products, filter }: Props) {
const filteredProducts = useMemo(() => {
return products
.filter(p => p.category === filter.category)
.filter(p => p.price >= filter.minPrice && p.price <= filter.maxPrice)
.sort((a, b) => a.name.localeCompare(b.name));
}, [products, filter.category, filter.minPrice, filter.maxPrice]);
return (
<ul>
{filteredProducts.map(p => <ProductCard key={p.id} product={p} />)}
</ul>
);
}
// ❌ Don't overuse - simple operations don't need memoization
const total = useMemo(() => a + b, [a, b]); // Overkill!
```
### useCallback
Memoize functions to prevent child re-renders:
```tsx
function Parent() {
const [count, setCount] = useState(0);
// ✅ Stable reference for child components
const handleClick = useCallback((id: string) => {
console.log('Clicked:', id);
}, []);
// ✅ Dependencies that change function behavior
const handleSubmit = useCallback((data: FormData) => {
submitWithCount(data, count);
}, [count]);
return (
<>
<ChildComponent onClick={handleClick} />
<Form onSubmit={handleSubmit} />
</>
);
}
```
---
## Virtualization
Render only visible items for large lists:
```tsx
import { FixedSizeList } from 'react-window';
function VirtualList({ items }: { items: Item[] }) {
const Row = ({ index, style }: { index: number; style: CSSProperties }) => (
<div style={style} className="list-item">
{items[index].name}
</div>
);
return (
<FixedSizeList
height={400}
width="100%"
itemCount={items.length}
itemSize={50}
>
{Row}
</FixedSizeList>
);
}
```
### With TanStack Virtual
```tsx
import { useVirtualizer } from '@tanstack/react-virtual';
function VirtualList({ items }: { items: Item[] }) {
const parentRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 50,
overscan: 5,
});
return (
<div ref={parentRef} style={{ height: 400, overflow: 'auto' }}>
<div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>
{virtualizer.getVirtualItems().map((virtualItem) => (
<div
key={virtualItem.key}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: virtualItem.size,
transform: `translateY(${virtualItem.start}px)`,
}}
>
{items[virtualItem.index].name}
</div>
))}
</div>
</div>
);
}
```
---
## Code Splitting
### Route-based Splitting
```tsx
import { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./pages/Home'));
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
function App() {
return (
<Suspense fallback={<PageLoader />}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}
```
### Component-based Splitting
```tsx
const HeavyChart = lazy(() => import('./HeavyChart'));
function Dashboard() {
const [showChart, setShowChart] = useState(false);
return (
<div>
<button onClick={() => setShowChart(true)}>Show Chart</button>
{showChart && (
<Suspense fallback={<ChartSkeleton />}>
<HeavyChart data={data} />
</Suspense>
)}
</div>
);
}
```
### Preloading
```tsx
const Dashboard = lazy(() => import('./Dashboard'));
const preloadDashboard = () => import('./Dashboard');
function NavLink() {
return (
<Link
to="/dashboard"
onMouseEnter={preloadDashboard}
onFocus={preloadDashboard}
>
Dashboard
</Link>
);
}
```
---
## Avoiding Unnecessary Re-renders
### Stable References
```tsx
// ❌ Bad: New object on every render
function Parent() {
return <Child style={{ color: 'red' }} />;
}
// ✅ Good: Stable reference
const style = { color: 'red' };
function Parent() {
return <Child style={style} />;
}
// ✅ Good: useMemo for dynamic values
function Parent({ color }) {
const style = useMemo(() => ({ color }), [color]);
return <Child style={style} />;
}
```
### Component Composition
```tsx
// ❌ Bad: Entire component re-renders on count change
function App() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(c => c + 1)}>{count}</button>
<ExpensiveComponent /> {/* Re-renders on every count change! */}
</div>
);
}
// ✅ Good: Move state down
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
function App() {
return (
<div>
<Counter />
<ExpensiveComponent /> {/* Doesn't re-render! */}
</div>
);
}
// ✅ Good: Pass children as props
function Counter({ children }) {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(c => c + 1)}>{count}</button>
{children} {/* Doesn't re-render! */}
</div>
);
}
```
---
## State Management Optimization
### Batching Updates
```tsx
// React 18+ automatically batches these
function handleClick() {
setCount(c => c + 1);
setFlag(f => !f);
setText('updated');
// Only ONE re-render!
}
```
### Derived State
```tsx
// ❌ Bad: Synchronized state
function Form() {
const [items, setItems] = useState([]);
const [total, setTotal] = useState(0);
useEffect(() => {
setTotal(items.reduce((sum, item) => sum + item.price, 0));
}, [items]); // Extra re-render!
}
// ✅ Good: Calculate during render
function Form() {
const [items, setItems] = useState([]);
const total = items.reduce((sum, item) => sum + item.price, 0);
}
// ✅ Good: useMemo for expensive calculations
function Form() {
const [items, setItems] = useState([]);
const total = useMemo(
() => items.reduce((sum, item) => sum + item.price, 0),
[items]
);
}
```
---
## Common Pitfalls
| Issue | Cause | Solution |
|-------|-------|----------|
| Slow initial render | Large bundle | Code splitting, lazy loading |
| Slow updates | Too many re-renders | memo, useMemo, useCallback |
| Janky scrolling | Rendering all list items | Virtualization |
| Memory leaks | Uncleaned effects | Proper cleanup functions |
| Layout thrashing | Forced synchronous layout | Batch DOM reads/writes |
## Best Practices
- ✅ Profile before optimizing
- ✅ Use React DevTools Profiler
- ✅ Virtualize long lists (>100 items)
- ✅ Code split at route level
- ✅ Memoize expensive computations
- ✅ Use stable references for objects/functions
- ❌ Don't over-optimize prematurely
- ❌ Don't wrap everything in memo
- ❌ Don't block main thread with heavy JS
## When NOT to Use This Skill
- **React 19 Compiler optimization** - Use `react-19` skill for compiler-specific features
- **Basic React development** - Use `react` skill for general component development
- **Testing** - Use `react-testing` skill for performance testing strategies
- **Non-performance React issues** - This skill is specifically for optimization
## Anti-Patterns
| Anti-Pattern | Problem | Solution |
|--------------|---------|----------|
| Premature optimization | Wasted effort, complex code | Profile first, optimize what matters |
| Wrapping everything in memo | Overhead, no benefit | Only memoize expensive components |
| useMemo for cheap calculations | More overhead than savings | Only memoize expensive operations |
| Inline object/function in JSX | Breaks child memoization | Extract to constant or useCallback |
| Not using key prop correctly | Full list re-render | Use stable unique IDs |
| Rendering entire list | Slow scrolling | Use virtualization for >100 items |
| Large bundle without code splitting | Slow initial load | Split by routes |
## Quick Troubleshooting
| Issue | Likely Cause | Fix |
|-------|--------------|-----|
| Slow initial load | Large bundle size | Code split, lazy load routes |
| Janky scrolling | Rendering all list items | Use react-window or TanStack Virtual |
| Frequent unnecessary re-renders | Props changing identity | Memoize objects/functions with useMemo/useCallback |
| Slow component updates | Heavy computation in render | Move to useMemo or Web Worker |
| Memory leaks | Uncleaned effects/subscriptions | Add cleanup functions to useEffect |
| Large JavaScript payload | Not tree-shaking | Import only what you need |
## Reference Documentation
- [React Profiler](https://react.dev/reference/react/Profiler)
- [Performance Optimization](https://react.dev/learn/render-and-commit)
- MCP: `mcp__documentation__fetch_docs` → technology: `react`, topic: `performance`
Files in this package (2)
- SKILL.md 11 KB
- advanced.md 5 KB
Versions
| Repository | Score | Licence |
|---|---|---|
| This page · claude-dev-suite/claude-dev-suite | 100 | MIT |
| Sanit-mann/The-Insectoids | 100 | MIT |
| HoangNguyen0403/agent-skills-standard | 100 | MIT |
| ssvinar/senior-agent-skills | 100 | MIT |
| krishna-modi12/frontend-design-pro | 100 | MIT |
| SHRIJANAGAIN/Nemo-Cli | 95 | Apache-2.0 |
| ginaservice/ginaservice-skills | 95 | MIT |
| TheBushidoCollective/han | 95 | Apache-2.0 |
| adilkalam/orca | 95 | MIT |
Database snapshot: 13.11.2026 · package version 6c6be92ca670 (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100react-performance-optimizer
Optimize React apps for 60fps performance. Implements memoization, virtualization, code splitting, bundle optimization. Use for slow renders, large lists, bundle bloat. Activate on "React performance", "slow render", "useMemo", "bundle size", "virtualization". NOT for backend… - 100react-native-web-performance
Use when optimizing React Native Web performance. Provides patterns for code splitting, bundle optimization, memoization, and web-specific performance improvements. - 100react-performance-optimization
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. - 95react-native-performance
Use when optimizing React Native app performance. Covers FlatList optimization, memoization, image optimization, bundle size reduction, and profiling techniques. - 100react-vite-best-practices
React and Vite performance optimization guidelines. Use when writing, reviewing, or optimizing React components built with Vite. Triggers on tasks involving Vite configuration, build optimization, code splitting, lazy loading, HMR, bundle size, or React performance. - 100performance-optimization
Optimize application performance for speed, efficiency, and scalability. Use when improving page load times, reducing bundle size, optimizing database queries, or fixing performance bottlenecks. Handles React optimization, lazy loading, caching, code splitting, and profiling.