React Performance Basics ⚙️
Performance tuning is about preventing unnecessary work. In Next.js, this means minimizing re-renders and keeping expensive calculations cached.
Rerender Triggers 🔔
A component re-renders when:
- Its state changes.
- Its props change (shallow comparison).
- A parent re-renders (and passes new references).
Map these triggers to understand hot paths.
memo & Pure Components 🧊
const PriceTag = memo(function PriceTag({ value }: { value: number }) {
return <span>${value.toFixed(2)}</span>;
});memoskips renders when props are shallow-equal.- Useful for list items or widgets receiving stable props.
useMemo & useCallback 🧠
- Cache expensive computations or handlers passed to memoized children.
- Keep dependency arrays tight; include everything used inside.
- Avoid wrapping everything—memoization adds overhead.
Refs for Stable Objects 📌
const configRef = useRef({ theme: 'dark' });- Store mutable objects outside render to avoid new references each render.
Split Server & Client ⚖️
- Heavy computations? Keep them in server components so work happens once per request.
- Client components should focus on interactivity/minimal state.
Profiling 🔬
- Use React DevTools Profiler to spot hot components.
- In Next.js, use
next dev --turbo+ Chrome Performance panel to see hydration costs.
Quick Wins ✅
- Derive state instead of duplicating (
const filtered = useMemo(() => ..., [items])). - Debounce input handlers hitting network APIs.
- Use key props wisely so React can reuse DOM nodes.
Analogy: think of React rendering like a kitchen—memoization is meal prep, refs are pantry staples, and profiling is checking which station causes delays.
Tackle obvious rerender culprits first, then iterate with profiling data. 🧑🍳
Last updated on