frontendMIT License Official
React Performance
Optimize React applications for rendering speed, eliminates unnecessary re-renders, bundle splitting, and memoization guidelines.
#React#Performance#Memoization#Bundle-Size#Profiler
Install for:
npx domoskills add react-performance
Security verified • Score: 100/100
Installs into:
.agent/skills/react-performanceSKILL.md Prompt Instructions
Read by AI agent on demand---
name: react-performance
description: Optimize React applications for rendering speed, bundle size, memoization, and component architecture.
license: MIT
version: 1.4.2
---
# React Performance Optimization
## Overview
React performance is about ensuring your application renders only what is necessary, when it is necessary, with minimum JavaScript sent to the browser. Poor performance manifests as jank, slow TTI, and degraded Core Web Vitals (LCP, CLS, INP).
## 1. Profile Before Optimizing
- Use React DevTools Profiler (Flamegraph + Ranked view) to identify expensive components.
- Record a session during the exact interaction that feels slow.
- Look for components with high "render duration" and high "render count".
- Use `console.time` / `console.timeEnd` around expensive computations during development.
## 2. Eliminate Unnecessary Re-renders
### useMemo
```tsx
// Memoize when computation is expensive (O(n log n) or heavier)
const sortedItems = useMemo(() => items.slice().sort(compareFn), [items]);
// Pointless — primitive derivation is cheaper than memo bookkeeping
// const count = useMemo(() => items.length, [items]);
```
### useCallback
```tsx
// Stabilize callback identity passed to memoized children
const handleDelete = useCallback((id: string) => {
dispatch({ type: "DELETE", payload: id });
}, [dispatch]);
```
### React.memo
```tsx
// Wrap pure leaf components that receive stable props
export const SkillCard = React.memo(({ skill }: Props) => { ... });
// Do not wrap components that always re-render due to context changes
```
## 3. Context Partitioning
Fat contexts cause every consumer to re-render on any field change.
```tsx
// Bad: one giant context
// const AppContext = createContext({ user, theme, cart, notifications });
// Good: split into domain-specific contexts
const UserContext = createContext<User | null>(null);
const CartContext = createContext<CartState>(defaultCart);
const ThemeContext = createContext<"light" | "dark">("dark");
```
For high-frequency updates (mouse, scroll, animation) use Zustand, Jotai, or Valtio — React Context is not designed for >30 updates/second.
## 4. Code Splitting & Dynamic Imports
```tsx
// Next.js
const HeavyChart = dynamic(() => import("./HeavyChart"), { ssr: false });
// React Router / Vite
const AdminPanel = React.lazy(() => import("./AdminPanel"));
// Rule: any component > 30KB minified should be code-split
```
Target: initial JS bundle <= 100 KB gzipped; route chunks <= 50 KB gzipped.
## 5. Virtualization for Long Lists
Never render more than ~200 DOM nodes in a list at once.
```tsx
import { useVirtualizer } from "@tanstack/react-virtual";
// or
import { FixedSizeList } from "react-window";
```
Use `react-window` for simple fixed-height rows; use `@tanstack/react-virtual` for variable-height or grid layouts.
## 6. Image Optimization
- Always use `next/image` — provides lazy loading, WebP/AVIF conversion, and srcset generation.
- Provide explicit `width` and `height` to eliminate CLS.
- Use `priority` only for the largest above-the-fold image (LCP candidate).
## 7. State Colocation
Keep state as close as possible to where it is consumed. Lifting state unnecessarily causes entire subtrees to re-render.
## 8. Avoid Object/Array Literals in JSX
```tsx
// Bad: creates new reference every render, breaks memo
// <Component style={{ padding: 16 }} items={[a, b, c]} />
// Good
const STYLE = { padding: 16 } as const;
<Component style={STYLE} items={ITEMS} />
```
## 9. Core Web Vitals Targets
| Metric | Good | Needs Improvement |
|--------|------|-------------------|
| LCP | <= 2.5s | 2.5s-4.0s |
| INP | <= 200ms | 200ms-500ms |
| CLS | <= 0.1 | 0.1-0.25 |
## 10. Anti-Patterns
- Using useEffect to synchronize derived state — compute it inline.
- Storing server data in useState — use TanStack Query or SWR.
- Anonymous functions in JSX passed to memoized children.
- Reading from Zustand inside render without selector memoization.
## References
- React Compiler (React 19): https://react.dev/learn/react-compiler
- Million.js block-based diffing: https://million.dev
- Chrome DevTools Performance Panel: https://developer.chrome.com/docs/devtools/performance/Ecosystem Radar & Recommended Companions
Standard Connectors
Antigravity (.agent)Claude Code (.claude)Cursor (.cursor)
React PerformanceActive Capability
Frequently Stacked With