Aller au contenu principal
Développement Web · 12 min de lecture

React Compiler stable : la fin de useMemo et useCallback

React Compiler est stable : mémoïsation automatique, composants optimisés par défaut, adoption dans Next.js 16. Ce qui change pour vos projets React en 2026.

Par L'équipe ConsilioWEB
React Compiler stable : la fin de useMemo et useCallback
Sommaire

React Compiler est stable en 2026 et rend la mémoïsation manuelle obsolète dans la plupart des composants React. Plus besoin d'écrire useMemo, useCallback ou React.memo à la main : le compilateur les génère automatiquement à la compilation.

C'est une rupture franche avec cinq ans d'habitudes front-end. Depuis React 16, les équipes ajoutaient ces hooks partout — souvent par réflexe, rarement à bon escient. Selon le State of React 2026, plus de 4 développeurs front sur 5 utilisent React 19 en production. Avec la stabilisation de React Compiler, le modèle de programmation React change en profondeur.

Chez ConsilioWEB, nous construisons les projets de nos clients en Next.js 16. L'activation du compilateur fait désormais partie de notre checklist de démarrage sur chaque nouveau projet. Dans cet article, vous apprendrez comment il fonctionne, comment l'activer sur votre stack, et ce que vous devez faire avec votre code existant.

React Compiler : pourquoi c'était attendu

Optimiser les re-renders React reposait entièrement sur le développeur pendant des années. La recette était connue : entourer les calculs coûteux de useMemo, stabiliser les fonctions avec useCallback, mémoïser les composants enfants avec React.memo. Simple en théorie. Pénible en pratique.

Le problème principal : ces optimisations sont fragiles et difficiles à maintenir. Un tableau de dépendances incorrect, et la mémoïsation ne sert à rien. Un useCallback oublié sur la prop d'un composant enfant, et ce composant re-render inutilement à chaque rendu parent. Pire encore : de nombreux développeurs ajoutent useMemo par précaution, même sur des calculs triviaux. Le code s'alourdit sans bénéfice mesurable.

L'idée de React Compiler remonte à la React Conf 2021, où Meta a présenté le projet "React Forget". Le principe : déplacer l'optimisation vers l'étape de compilation plutôt que vers le code source. L'équipe a travaillé plusieurs années pour rendre cette analyse statique fiable à grande échelle, sur des composants réels de production.

Le projet est passé en bêta avec React 19 fin 2024, puis a atteint la stabilité courant 2025. Il s'appelle désormais React Compiler — exit le nom de code. Les principaux frameworks ont suivi rapidement : Next.js 15 a ouvert la voie, Next.js 16 l'intègre en option stable.

C'est la première évolution aussi fondamentale du modèle React depuis l'introduction des Hooks en 2018. Pour les équipes qui maintiennent de gros codebases, c'est un soulagement. Moins de code défensif, moins de bugs subtils liés aux dépendances, moins de débats en code review sur les hooks. Le compilateur prend en charge ce travail mécanique à votre place.

Comment fonctionne la mémoïsation automatique

Analyse statique à la compilation

React Compiler est un plugin Babel (ou SWC). Il s'exécute au moment du build, pas au runtime. Il analyse le code source de chaque composant sous forme d'arbre syntaxique abstrait (AST), identifie les valeurs stables entre les rendus, et génère automatiquement les mémoïsations nécessaires.

Le résultat est du JavaScript standard. Votre code source reste lisible et concis. Le code optimisé — équivalent aux useMemo, useCallback et React.memo — apparaît uniquement dans le bundle final.

Ce que le compilateur optimise concrètement

Prenons un exemple typique :

1function ProductCard({ product, onAddToCart }) {
2 const displayPrice = formatPrice(product.price, product.currency);
3
4 return (
5 <div className="card">
6 <h2>{product.name}</h2>
7 <p>{displayPrice}</p>
8 <button onClick={onAddToCart}>Ajouter au panier</button>
9 </div>
10 );
11}

Le compilateur détecte que displayPrice dépend uniquement de product.price et product.currency. Il génère l'équivalent d'un useMemo sur ce calcul. Il stabilise aussi la référence à onAddToCart si le parent peut la mémoïser en amont.

Sans le compilateur, il aurait fallu écrire le useMemo manuellement, envelopper le composant dans React.memo, et s'assurer que le parent stabilise onAddToCart via useCallback. Avec le compilateur, vous n'écrivez rien de tout ça.

Ce que le compilateur laisse passer

Le compilateur ne fait pas de magie. Il ne peut pas optimiser un composant qui viole les Règles de React. Si votre rendu produit des effets de bord, mute des props ou dépend de valeurs non déterministes, le compilateur ignore simplement ce composant. Il le laisse tel quel plutôt que de risquer un comportement incorrect.

Par conception, il est conservateur : il préfère ne rien optimiser plutôt que d'optimiser de manière incorrecte. C'est pour ça que la conformité aux Règles de React est critique.

Ce qu'il ajoute dans le bundle

L'analyse du compilateur se traduit par des appels à react/compiler-runtime dans le bundle. Ce runtime léger gère la mémoïsation de bas niveau. Il fonctionne uniquement avec React 19, qui expose les primitives internes nécessaires. React 18 n'est donc pas compatible.

Illustration : Comment fonctionne la mémoïsation automatique

Comment l'activer dans Next.js 16 et Vite

Activer React Compiler dans Next.js 16

L'activation dans Next.js 16 est triviale. Ouvrez votre next.config.ts et ajoutez l'option reactCompiler :

1// next.config.ts
2import type { NextConfig } from 'next'
3
4const nextConfig: NextConfig = {
5 experimental: {
6 reactCompiler: true,
7 },
8}
9
10export default nextConfig

Redémarrez le serveur de développement. Le compilateur s'active immédiatement sur l'ensemble de vos composants. Next.js 16 utilise SWC en interne pour cette transformation — le build reste rapide.

Activer React Compiler dans Vite

Pour un projet Vite, installez d'abord les dépendances nécessaires :

1npm install -D babel-plugin-react-compiler @vitejs/plugin-react

Ensuite, configurez vite.config.ts :

1// vite.config.ts
2import { defineConfig } from 'vite'
3import react from '@vitejs/plugin-react'
4
5export default defineConfig({
6 plugins: [
7 react({
8 babel: {
9 plugins: ['babel-plugin-react-compiler'],
10 },
11 }),
12 ],
13})

Cette configuration utilise Babel, pas SWC. Le build sera légèrement plus lent. Pour les projets qui adoptent Vite 6 et Rolldown, vérifiez la compatibilité de votre version de @vitejs/plugin-react avant de basculer Rolldown en bundler principal.

Adoption progressive avec 'use memo'

Sur un projet existant, vous n'êtes pas obligé d'activer le compilateur sur tout d'un coup. La directive 'use memo' en tête d'un fichier active le compilateur uniquement pour ce composant :

1'use memo'
2
3export function HeavyDataTable({ rows }) {
4 // Le compilateur optimise uniquement ce composant
5 return <table>...</table>
6}

L'inverse est aussi possible : 'use no memo' désactive le compilateur pour un composant précis. C'est pratique pour les rares cas où vous voulez garder la main sur la mémoïsation.

Ajouter le plugin ESLint

Installez également eslint-plugin-react-compiler. Il signale les violations des Règles de React dans votre éditeur avant même la compilation :

1npm install -D eslint-plugin-react-compiler
1// eslint.config.js
2import reactCompiler from 'eslint-plugin-react-compiler'
3
4export default [
5 {
6 plugins: { 'react-compiler': reactCompiler },
7 rules: { 'react-compiler/react-compiler': 'error' },
8 },
9]

Ce plugin est la première chose à activer. Il vous indique exactement quels composants le compilateur optimisera et lesquels il ignorera. Si vous utilisez déjà Biome à la place d'ESLint et Prettier, conservez ESLint uniquement pour ce plugin — les deux outils peuvent coexister sans conflit.

useMemo et useCallback : faut-il tout supprimer ?

La réponse courte : pas immédiatement, mais dans la grande majorité des cas, oui.

Ce que vous pouvez retirer sans risque

Avec React Compiler actif, les situations suivantes sont entièrement gérées. Vous pouvez supprimer les annotations manuelles sans craindre de régression :

  • React.memo sur des composants purs qui reçoivent des props simples
  • useMemo pour des calculs dérivés de props ou de state (formatage, filtrage, tri, agrégations)
  • useCallback sur des fonctions passées à des composants enfants purs
  • React.memo combiné à useCallback sur des handlers d'événements

Supprimer ces annotations allège le code. Moins de lignes, moins de tableaux de dépendances à surveiller, moins de risques d'erreur lors des refactos futures.

Ce que vous devez évaluer au cas par cas

Certains cas méritent une analyse avant de retirer la mémoïsation manuelle :

Situation

Recommandation

Tri ou filtrage de milliers d'éléments

Conserver useMemo avec commentaire explicatif

Référence stable attendue par une librairie tierce

Tester le comportement après suppression

useMemo avec logique complexe hors scope React

Le compilateur reste prudent — vérifier

React.memo avec areEqual personnalisé

À conserver : comparaison custom non gérée

Hooks custom retournant des callbacks stables

Évaluer selon les consommateurs du hook

Faut-il migrer tout le code existant immédiatement ?

Non. Conserver des useMemo et useCallback superflus ne crée pas de bug. Le compilateur les respecte et ajoute ses propres optimisations par-dessus. Il y a une légère redondance, mais aucune régression fonctionnelle.

Migrez progressivement. Commencez par les nouveaux composants — écrivez-les sans mémoïsation manuelle dès le départ. Nettoyez l'existant lors des refactos normales, fichier par fichier. Le plugin ESLint signale les composants déjà optimisés par le compilateur : utilisez cet indicateur pour prioriser votre effort.

Les règles de React que le compilateur impose

React Compiler exige que vos composants respectent les Règles de React à la lettre. Ces règles existaient déjà avant le compilateur, mais elles étaient souvent ignorées sans conséquence immédiate. Avec le compilateur, les violations ont un effet direct : le composant n'est pas optimisé.

Les violations les plus fréquentes

Voici ce que nous rencontrons le plus souvent sur des codebases existants :

  • Mutation directe de props ou de state : items.push(newItem) dans le rendu est interdit. Créez un nouveau tableau avec le spread ou concat.
  • Effets de bord pendant le rendu : appels réseau, manipulations DOM directes, écriture en base — tout cela appartient à un useEffect.
  • Références mutées dans le rendu : modifier ref.current pendant le rendu viole la pureté du composant.
  • Valeurs non déterministes : Date.now() ou Math.random() dans le rendu produisent des résultats différents à chaque appel. Le compilateur ne peut pas les mémoïser.
  • Hooks appelés conditionnellement : if (condition) { useMemo(...) } reste strictement interdit par les Règles de React.
  • Objets partagés mutés : modifier un objet défini à l'extérieur du composant crée un état partagé implicite invisible.

Comment nettoyer un codebase existant

La première activation de eslint-plugin-react-compiler sur un projet avec du code legacy peut révéler des dizaines de violations. C'est normal — procédez par ordre de priorité :

  1. Listez tous les composants que le compilateur ignore (le plugin ESLint les marque avec une erreur).
  2. Triez-les par importance : composants à fort trafic, composants réutilisés partout, composants de listes longues.
  3. Corrigez les violations une par une, en commençant par les mutations directes — 60 à 70 % des cas.
  4. Vérifiez visuellement et via vos tests que le comportement est identique après chaque correction.

La bonne nouvelle : corriger ces violations améliore la qualité générale du code, indépendamment du compilateur. Notre article sur les Server Actions Next.js aborde des principes adjacents sur la pureté des fonctions côté serveur — les deux sujets se recoupent souvent lors d'un audit.

Résultats mesurés sur un projet réel

Contexte et configuration

Voici les chiffres observés sur un projet e-commerce B2B — catalogue produits avec filtres avancés, tableau de bord de commandes, interface de gestion des stocks. La stack : Next.js 16, TypeScript strict, environ 200 composants, 14 000 lignes de JSX/TSX.

L'équipe avait une couverture useMemo/useCallback jugée correcte avant l'activation. Environ 420 lignes d'annotations manuelles au total.

Avant et après : les métriques

Métrique

Avant

Après

Delta

Re-renders inutiles (React Profiler)

~340 / interaction

~90 / interaction

−74 %

Time to Interactive (TTI médian)

2,4 s

2,1 s

−13 %

INP (Interaction to Next Paint)

185 ms

118 ms

−36 %

Lignes de mémoïsation manuelle

420

88

−79 %

Taille bundle JS gzip

138 KB

144 KB

+4 %

Le bundle augmente légèrement. C'est attendu : le compilateur ajoute ses wrappers dans le code généré. En revanche, les gains à l'exécution compensent largement ce surcoût réseau sur la grande majorité des connexions.

Ce qui a le plus changé

Le gain le plus visible concerne les listes longues. Un tableau de 500 lignes de commandes re-rendait intégralement à chaque filtre appliqué. Avec le compilateur, seules les lignes dont les données changent se re-rendent. L'interface est nettement plus fluide.

Par ailleurs, l'équipe passe moins de temps à déboguer des boucles de re-render. Les bugs liés à des tableaux de dépendances incorrects ont disparu. C'est difficile à quantifier, mais l'impact sur la vélocité de développement est réel.

Pour les optimisations côté rendu serveur, notre article sur le Streaming SSR avec React 19 et Suspense couvre les techniques complémentaires — les deux approches se combinent très bien.

Les limites à connaître

Le compilateur ne fait rien sur les composants qui violent les Règles de React. Sur un petit projet avec peu de re-renders, le gain est faible. Et la légère augmentation de bundle est à surveiller sur des connexions très lentes ou des devices d'entrée de gamme.

L'essentiel : mesurez avant et après. Le React DevTools Profiler reste votre meilleur outil pour quantifier les gains réels. Ne supposez pas — profilez.

Si vous utilisez TanStack Start ou un autre framework full-stack React, les gains sont similaires. React Compiler s'applique au niveau du composant, indépendamment du framework de routing ou de data-fetching sous-jacent.

Questions fréquentes sur React Compiler

React Compiler fonctionne-t-il avec React 18 ?

Non. React Compiler nécessite React 19 minimum. Il utilise des primitives de runtime intégrées dans React 19, notamment react/compiler-runtime. Si votre projet est encore sur React 18, planifiez d'abord cette migration. Elle est généralement non-cassante pour la plupart des projets bien écrits.

Peut-on activer React Compiler progressivement sur un projet existant ?

Oui, et c'est la stratégie recommandée. Utilisez la directive 'use memo' en tête des fichiers à optimiser en priorité. Inversement, 'use no memo' désactive le compilateur sur un composant précis. Cette granularité permet une adoption sans risque, module par module.

React Compiler remplace-t-il totalement React.memo ?

Dans la majorité des cas, oui. Le compilateur mémoïse les composants qui reçoivent des props identiques. Cependant, React.memo avec une fonction areEqual personnalisée reste nécessaire quand vous avez besoin d'une logique de comparaison custom — par exemple, comparer des objets complexes par valeur plutôt que par référence.

Le code généré est-il débuggable ?

Le code dans le bundle n'est pas destiné à être lu directement. En mode développement, les DevTools de votre navigateur permettent d'inspecter la transformation. Le React Compiler Playground sur react.dev visualise la transformation en temps réel. Dans vos fichiers source, rien ne change — vous écrivez des composants propres, le compilateur fait le reste.

Qu'arrive-t-il aux composants que le compilateur ne peut pas optimiser ?

Ils fonctionnent exactement comme avant l'activation. Le compilateur ignore les composants en violation et les laisse intacts. Il n'y a aucune régression fonctionnelle. La seule conséquence est l'absence d'optimisation automatique sur ces composants — vous devrez gérer leur mémoïsation manuellement, comme avant.

Conclusion

React Compiler marque une étape majeure dans l'évolution de React. La mémoïsation manuelle — source de code verbeux et de bugs subtils — appartient désormais au passé pour la grande majorité des composants. Ce n'est pas une optimisation optionnelle de plus : c'est le nouveau fonctionnement par défaut de React en 2026.

L'activation est simple sur Next.js 16. Elle demande un travail de nettoyage sur les codebases legacy avec des violations des Règles de React. Mais ce chantier vaut la peine : un code plus pur, des gains mesurables sur l'INP et les re-renders, et une base saine pour la suite.

Vous souhaitez activer React Compiler sur votre projet Next.js ou auditer un codebase React existant pour identifier les violations ? Notre équipe à Ussel accompagne les PME et les équipes techniques dans ce type de migration — analyse du codebase, priorisation des violations, mise en place progressive. Contactez-nous via le formulaire de devis pour discuter de votre projet.

Pour aller plus loin

Partager
Un projet en tête ?Discutons de votre projet web et transformons vos idées en réalité.
Devis gratuit →