3 Sept 2026•3 min read
Automatic memoization removed a whole category of busywork from React codebases. It also exposed which of our performance habits were cargo cult all along.
6 September 2026•4 min read
For most of React's history, a meaningful share of code review time went to a question no product manager ever asked: should this be wrapped in useMemo? The compiler settles it. Components get memoized automatically, dependency arrays stop being hand-maintained trivia, and a class of subtle bugs caused by a forgotten dependency simply disappears.
What is more interesting is what the change reveals. Once the compiler removes the busywork, you find out how much of your performance culture was actually about performance and how much was ritual.
Three real problems go away. First, the referential-identity tax: passing callbacks to memoized children no longer requires a chain of useCallback wrappers whose only purpose is to preserve identity. Second, stale-closure bugs from incomplete dependency arrays, which were always the compiler's job to catch and never the human's. Third, the readability cost, since a component body that reads top to bottom without memo scaffolding is dramatically easier to review.
If your app was slow because of unnecessary re-renders in medium-sized trees, you will see a real improvement for free. That is a genuine win and it applies to a lot of ordinary product code.
Almost everything that made apps actually slow is untouched. The compiler will not shrink your bundle, will not make a waterfall of requests parallel, will not stop you fetching four hundred rows to render ten, and will not rescue a layout that thrashes on every scroll event. It does not know that your date library is two hundred kilobytes, or that a component mounts an expensive chart before the user has scrolled anywhere near it.
The honest ranking of what determines perceived speed has not moved: how much JavaScript you ship, how many round trips you need before first paint, how much data you transfer, and how much work you do on the main thread during interaction. Memoization was always fourth or fifth on that list and it is now handled for you.
Keep memoizing genuinely expensive pure computations, because the compiler optimises re-render work, not an O(n log n) transform over a large array. Keep virtualising long lists. Keep stabilising values that cross a boundary the compiler cannot see, such as objects handed to a non-React library or a context value consumed by hundreds of subscribers. And keep profiling before you optimise, which is the only rule on this list that has never changed.
The practical path is unexciting: enable it, run your test suite, and look for components that were quietly depending on referential instability, usually via a useEffect that fired on identity change rather than on real data change. Those effects were bugs before; the compiler just makes them visible. Fix the effect, not the compiler.
Tooling that removes a decision is worth more than tooling that makes the decision faster. The best outcome of the React Compiler is that a generation of developers will never learn to think in dependency arrays.
Spend the time you get back on the things the compiler cannot touch. Audit your bundle. Move a request to the server. Cut a waterfall. Those are still the levers, and they are still worth pulling by hand.
@umarrafique923
Author and writer at CandyWrite. Sharing knowledge, tutorials, and reflections on technology, design, and ideas.
Join 12,000+ readers getting our Saturday morning editorial dispatch with our top essays and reading recommendations.
3 Sept 2026•3 min read
2 Sept 2026•3 min read
5 Sept 2026•4 min read
8 Sept 2026•5 min read
Discussion (0)
Join the conversation. Sign in to leave a response or reply to comments.