The React Compiler is a build-time tool that automatically optimizes React applications through automatic memoization. It aims to reduce or eliminate the need for manual performance optimizations like useMemo, useCallback, and React.memo.
React Compiler analyzes your code at build time and automatically:
- Memoizes function references (similar to
useCallback) - Memoizes computed values (similar to
useMemo) - Optimizes component re-renders (similar to
React.memo)
This workshop includes two interactive examples that demonstrate what React Compiler can and cannot optimize:
File: src/pages/performance/page1/Problem.tsx
Setup:
MovieBasiccomponent WITHOUTReact.memo- Parent component re-renders every second (views update)
- Child props (
title,year,showtimes) don't change
Question: Does React Compiler prevent MovieBasic from re-rendering?
Compare with: src/pages/performance/page1/Solution2Memo.tsx (uses manual React.memo)
File: src/pages/performance/page2/Problem.tsx
Setup:
MemoizedMoviecomponent WITHReact.memo- Handler function
handleToggleWatchlistrecreated every render - New function reference breaks
React.memoshallow comparison
Question: Does React Compiler fix this by automatically memoizing the handler?
Compare with: src/pages/performance/page2/Solution2UseCallback.tsx (uses manual useCallback)
Edit vite.config.ts and toggle the compiler:
const ReactCompilerConfig = {
sources: (_filename: string) => {
return true; // Enable: true | Disable: false
},
};-
With React Compiler DISABLED (
return false):- Run the app:
npm run dev - Open browser console
- Navigate to
/performance/1- observe console logs - Navigate to
/performance/2- observe console logs - Note which components re-render unnecessarily
- Run the app:
-
With React Compiler ENABLED (
return true):- Change config to
return true - Restart dev server
- Navigate to
/performance/1- observe console logs - Navigate to
/performance/2- observe console logs - Note which components still re-render
- Change config to
-
Compare Results:
- Which page does React Compiler help with?
- Which page still has unnecessary re-renders?
- Why the difference?
Open React DevTools Profiler while testing:
- Notice components may show as "Memoized by React Compiler"
- BUT they might still re-render!
- This reveals an important limitation
- ✅ Function memoization (Example 2): Automatically memoizes
handleToggleWatchlist, makingReact.memowork effectively - ✅ Value memoization: Automatically memoizes computed values within components
- ✅ Some component-level optimizations: In simple, isolated cases
- ❌ Component re-renders from parent updates (Example 1): Cannot reliably prevent child re-renders when parent updates, even when child props haven't changed
- ❌ Complex dependency tracking: May fail silently with certain patterns (e.g., non-memoized objects from third-party hooks)
- ❌ DevTools can be misleading: Components may show as "memoized" but still re-render
Even with React Compiler, MovieBasic re-renders because:
- Parent component (
MoviesList) re-renders whenviewsstate updates - React Compiler memoizes the component but the optimization fails in practice
- Manual
React.memoprovides a reliable, explicit boundary
React Compiler successfully fixes this because:
MemoizedMoviealready hasReact.memowrapper- Compiler automatically memoizes
handleToggleWatchlist(likeuseCallback) - Stable function reference →
React.memocomparison succeeds → no re-render
Students often wonder: "Arrays are reference types - shouldn't they break React.memo?"
Answer: The showtimes array has a stable reference because:
// movies.ts - Module-level constant
const movies = [
{
id: 1,
showtimes: [ /* Created ONCE when module loads */ ]
}
];- Array created once at module load time
- Destructuring
({ showtimes })extracts the same reference every render - Same reference →
===comparison succeeds →React.memoworks
This would break it:
// ❌ New array every render
<MovieBasic showtimes={[...showtimes]} />
// ❌ Movies recreated in component
const MoviesList = () => {
const movies = [ /* New array every render */ ];
}React Compiler v19.1.0-rc.2 (installed in this project):
- Stable and production-ready at Meta (Meta Quest Store)
- Excellent at memoizing functions and values
- Still has limitations with component-level optimizations
- Works alongside manual optimizations (no need to remove existing
useMemo/useCallback/React.memo)
React Compiler is a powerful tool that eliminates much manual memoization, but it's not magic:
- Reduces boilerplate for
useCallbackanduseMemo - Makes
React.memomore effective by memoizing function props - BUT manual
React.memois still valuable for reliable component-level optimization - Understanding memoization fundamentals remains crucial
- Official React Compiler Documentation
- React Compiler Introduction
- I tried React Compiler today - Real-world testing and limitations
- Meta's React Compiler 1.0 Announcement
- React Compiler Working Group
- In what scenarios would you still use manual
React.memoeven with React Compiler enabled? - Why might React DevTools show a component as "memoized" but it still re-renders?
- How does reference stability of props affect both manual
React.memoand React Compiler optimizations? - Should you remove all existing
useMemo,useCallback, andReact.memowhen adopting React Compiler?