En avril 2024, la première Release Candidate de React 19 est publiée. Comme nouveauté, nous avons, de nouveaux hooks
, les server components
et d’autres améliorations très pratiques, comme ref
disponible comme propriété par défaut dans tous les composants fonctionnels.
En parallèle de ces nouveautés pour la nouvelle version, React a annoncé l’introduction d’un compilateur !
Pourquoi un compilateur ?
La version 16.8 en 2019 de React introduit les hooks, rendant la réutilisation de code plus facile, et l’organisation de code plus flexible. Cependant avec cette amélioration viennent 2 hooks qui ne sont pas là pour faciliter la vie des développeurs, j’ai nommé useMemo
et useCallback
. Ces hooks sont avant tout destinés à améliorer les performances de React, en précisant quand il est nécessaire de recalculer une valeur ou de recréer une fonction.
Un petit rappel de comment sont utilisés useMemo
et useCallback
:
function App() {
const [count, setCount] = useState(0);
const [inputValue, setInputValue] = useState('');
const doubledCount = useMemo(() => {
return count * 2;
}, [count]);
const handleButtonClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<input value={inputValue} onChange={(e) => setInputValue(e.target.value)}/>
<button onClick={handleButtonClick}>Incrémenter</button>
<p>Compteur : {count}</p>
<p>Compteur doublé : {doubledCount}</p>
</div>
);
}
Ici, si l’on omet ces 2 hooks d’optimisation, doubledCount
sera recalculé et handleButtonClick
sera redéfini à chaque re-rendu du composant, même si count
(la seule propriété valorisée dans ces cas-là) ne change pas.
Ce travail, qui consiste à ajouter ces hooks d’optimisation, est encore à la charge du développeur alors qu’il semble pouvoir être automatisé. Même les configurations ESLint préviennent le développeur s’il manque des dépendances utilisées dans ces hooks.
Qui n’a jamais vu cette ligne dans une base de code React :
// eslint-disable-next-line react-hooks/exhaustive-deps
Le compilateur pour faire notre boulot
C’est donc ça le rôle du nouveau compilateur React, ajouter automatiquement les optimisations que l’on fait à la main jusqu’à maintenant. La première fois que le compilateur a été mentionné, c’était à la React conf 2021, il était désigné sous le nom “React Forget”.
Avec le “React Compiler”, nous n’avons plus à utiliser les hooks useMemo
et useCallback
et nous n’avons plus à déclarer nos composant dans un React.memo
(Ce dernier permet de ne re-rendre un composant que si ses props ont changés de valeur).
Une optimisation sous certaines conditions
Pour que le compilateur fonctionne, votre code doit respecter les règles de React. Ces règles assurent que React peut suivre correctement l’état de votre application et optimiser le rendu de vos composants.
Il faut par exemple :
- N’utiliser les hooks qu’au sommet des composants (pas de hooks exécuté de manière conditionnelle)
- Appeler les hooks uniquement dans des composants React ou des hooks personnalisés
- L’ordre d’appel des hooks doit être le même entre chaque re-rendu
Ce ne sont pas juste des bonnes pratiques, si on ne respecte pas les règles de React, on peut faire face à des comportements inattendus.
Si vous utilisez <StrictMode>
et que votre code ne désactive pas certaines règles eslint importantes (ex : eslint-disable react-hooks/rules-of-hooks
), il y a de grandes chances que votre code React suive ces règles.
Préparer sa migration
Il est déjà possible de vérifier si notre base de code sera bien optimisée par le compilateur. Plusieurs outils sont à notre disposition pour faciliter cette transition.
Script de vérification
Nous avons à notre disposition un script npx
que l’on peut appliquer à notre code :
npx react-compiler-healthcheck@latest
Successfully compiled 84 out of 88 components.
StrictMode usage found.
Found no usage of incompatible libraries.
Dans l’exemple ci-dessus, le script nous informe que 84 composants sur 88 peuvent être optimisés par le compilateur. Les 4 composants restants ne remplissent pas les conditions mentionnées précédemment, ils ne seront donc pas optimisés.
Malheureusement, nous n’avons pas encore la liste des composants en questions, une issue github accompagné d’une Pull Request est ouverte pour pallier ce problème.
Plugin eslint
Un plugin eslint existe permettant d’ajouter les règles eslint que l’on doit suivre pour que le React Compiler fonctionne. Il suffit de l’installer et de l’ajouter à notre configuration eslint :
npm install eslint-plugin-react-compiler
module.exports = {
plugins: [
'eslint-plugin-react-compiler',
],
rules: {
'react-compiler/react-compiler': "error",
},
}
Avec ce plugin, nous pouvons facilement identifier le code qui pose problème pour le compilateur.
Au-delà d’identifier les problèmes pour le compilateur, cela permet aussi d’identifier du code pouvant être refactorisé, car il ne suit pas les bonnes pratiques de React.
Si tous vos fichiers ne peuvent pas être compilés, ce n’est pas la fin du monde, le compilateur optimisera seulement ceux possibles et laissera tels quels ceux ne satisfaisant pas toutes ses conditions.
Utiliser le compilateur
Le React Compiler est un package distinct introduit avec React 19. Cependant, il est déjà possible de l’utiliser avec React 18 en suivant les instructions mentionnées dans cette discussion GitHub. Pour cela, il est notamment nécessaire d’ajouter un polyfill pour le hook de mémoïsation utilisé par le React Compiler. Vous pouvez trouver ce polyfill dans ce gist. Notez que ce hook sera automatiquement inclus dans React 19.
Cependant, même s’il est possible d’utiliser le React Compiler pour des versions de React inférieures à 19, il vaut mieux attendre que la version stable sorte. Avec React 19, vous pouvez vous référer à la documentation officielle pour obtenir des instructions détaillées sur l’utilisation du compilateur.
Une expérience développeur améliorée
À ce jour, il n’y a pas de date de sortie officielle pour la version stable de React 19.
Néanmoins, avec l’introduction du React Compiler et les autres nouveautés embarquées dans React 19, le framework promet une expérience développeur améliorée. React reste aujourd’hui le seul framework populaire qui délègue des optimisations de performances à la charge du développeur.