JavaScript Performance Patterns in React
This page covers practical JavaScript-level optimizations inside React components, based on patterns shown in Vercel's Introducing: React Best Practices and react-best-practices examples. The goal is not micro-optimizing everything - it is eliminating repeated work that compounds under real user interaction.
Combining Loop Iterations
A real pattern from Vercel examples: chat UIs repeatedly scanning the same messages list for different metrics, badges, and derived groups.
When the list is large (or updated frequently), this removes repeated iteration cost and GC pressure from intermediate arrays.
Lazy State Initialization
Vercel's real-world example pattern: parsing local storage config on every render.
The non-lazy version runs JSON.parse(...) on every re-render, but React ignores that value after the first render. That is wasted CPU.
Memoizing Stable Selectors
Inline sorting/filtering creates fresh arrays every render, even if inputs did not change.
Use React DevTools Profiler with "Why did this render?" enabled to confirm the selector output was triggering re-renders.
Avoiding Object Creation in Render
Common render-time allocation traps:
Fix guide:
- Inline style props -> hoist constant objects to module scope when static
- Hook config objects -> memoize values/functions used as options
new Date()/new RegExp()in render -> precompute or memoize intentionally
How to Profile Before Optimizing
Use React DevTools Profiler first, then optimize only measured hotspots.
// Recommended profiling routine:
// 1) Open React DevTools -> Profiler tab
// 2) Record while performing a realistic interaction
// 3) Sort by "Self time" and "Render duration"
// 4) Check "Why did this render?" for noisy components
// 5) Apply a targeted optimization
// 6) Re-profile and confirm the change helped
If performance did not improve measurably, revert the change and keep the simpler code.