The React performance checklist I run on every rescue project
Eight checks, in order, that find most React performance problems before anyone says the word "memo".
When a client says “our React app is slow”, the cause is almost never what the team thinks it is. Before touching useMemo, I run the same checklist, in the same order. It finds the real problem nine times out of ten.
1. Measure first
Open the Profiler, record the slow interaction, look at the flame graph. No exceptions. Optimizing unmeasured code is guesswork.
2. Network waterfalls
Most “render performance” complaints are actually fetching performance: sequential requests where each useEffect waits for the previous one. Fix the waterfall before the renders.
3. Bundle size
Check what’s actually shipped. I’ve found moment.js with all locales, three icon libraries, and an entire charting library imported for one sparkline. Run npx vite-bundle-visualizer or @next/bundle-analyzer: five minutes of work, often a big win.
4. Unstable references
Objects and arrays created inline in props, context values rebuilt every render. This is where re-render storms start, and it’s a code pattern problem rather than a memoization problem.
5. Giant lists
Anything rendering more than ~200 rows gets virtualized. No discussion.
6. Images
Unsized images that cause layout shifts, full-resolution photos in thumbnails. Boring checks, but they pay off.
7. State living too high
A keystroke in a search box shouldn’t re-render the page shell. Push state down to the component that needs it.
8. Only now: memoization
If the flame graph still shows expensive re-renders after all of the above, then memo and useMemo become precise tools instead of superstition.
The pattern behind the checklist: architecture problems first, micro-optimizations last. Memoization applied to a bad architecture just makes the bad architecture harder to read.