React is fast by default for most apps. Performance work starts with measuring — React DevTools Profiler identifies actual bottlenecks before you add memoization or splitting.
Measure Before Optimizing
Common causes of slow React apps: unnecessary re-renders, large lists without virtualization, unoptimized images, and heavy computation during render — not React itself being slow.
React 18 concurrent rendering, automatic batching, and transitions (useTransition) help keep UIs responsive during expensive updates.
Profile in production-like builds — dev mode is slower.
Fix architecture before sprinkling memo everywhere.
Split contexts to reduce subscriber re-renders.
Move heavy work off main thread or web workers if needed.
Performance Checklist
Steps before and during optimization.
Step
Action
Profile
React DevTools Profiler
Identify
Unnecessary re-renders or slow render
Fix root cause
State colocation, split context
Memoize
React.memo, useMemo, useCallback
Split code
React.lazy + Suspense
Virtualize
Long lists with TanStack Virtual
Why Components Re-render
Parent re-render, context change, state change, or prop reference change all trigger child re-renders unless memoized. Not every re-render is expensive — profile to find costly ones.
useTransition for Responsive UI
useTransition marks state updates as non-urgent, letting React keep the UI responsive during heavy renders like filtering large lists.