90 % des développeurs React optimisent incorrectement les re-renderings.
La plupart des développeurs React optimisent les re-render de la mauvaise manière. Où se situe réellement la performance de React et quels correctifs sont utiles, ainsi qu’une liste de contrôle pour les appliquer.
Sources: 90% of React Developers Optimize Re-Renders Incorrectly — Here’s What Actually Works
Les notes suivantes reconstituent une approche pratique autour du sujet « 90 % des développeurs React optimisent les re-render de manière incorrecte — Voici ce qui fonctionne réellement ». L’accent est mis sur les contrats, les vérifications et les placeholders de code interchangeables, plutôt que sur une approche motivante. Lors de la phase d’aperçu, notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Considérez cette phase comme un contrat entre les entrées et les sorties validées. Donnez des noms aux éléments générés, définez des vérifications de succès et refusez les terminations partielles silencieuses.
Le véritable problème : nous ne comprenons pas quand React re-render
Le véritable problème : nos étapes de développement fonctionnent le mieux lorsqu’elles sont traitées comme une surface mesurable. Capturez un exemple réussi, un cas d’échec ainsi que la note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le processus passe de la démonstration aux environnements partagés. Gardez les tâches de rendu peu coûteuses et reportez les calculs onéreux à l’après-mémorisation, uniquement après avoir effectué des mesures. Une mémorisation prématurée peut cacher des bugs liés à des données obsolètes.
Le jour où vous avez enfin ouvert React Profiler
The Day you Finally stage fonctionne le mieux lorsqu’il est considéré comme une surface mesurable. Capturez un exemple réussi, un cas d’échec et la note de réversion avant d’élargir le périmètre. Gardez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Maintenez le coût des opérations de rendu faible et reportez les calculs coûteux à la mise en mémoire uniquement après avoir effectué des mesures. Une mise en mémoire prématurée peut cacher des erreurs liées à des données obsolètes.
La vérité fondamentale : ce ne sont pas les re-rendus qui sont l’ennemi — ce sont ceux qui sont inutiles
La phase de ré-rendu de The Core Truth fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemple idéal, un cas d’échec et la note de rollback avant d’élargir le périmètre. Documentez ensemble le parcours réussi et celui de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Maintenez les coûts de rendu faibles et reportez les calculs coûteux à la mise en mémoire uniquement après avoir effectué des mesures. Une mise en mémoire prématurée peut cacher des bugs liés à des données obsolètes. La phase de ré-rendu de The Core Truth fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemple idéal, un cas d’échec et la note de rollback avant d’élargir le périmètre. Considérez cette phase comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définez des critères de succès et refusez toute complétion partielle silencieuse.
Section 1 : Le modèle mental qui a enfin fait fonctionner React
Pour la section 1 « Étape mentale », définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût des jetons ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le parcours passe d’un environnement de démonstration à des environnements partagés. Préférez les sorties structurées avec validation de schéma aux textes libres lorsque l’étape suivante consiste en du code ou une appel à outil.
React = Moteur d’exécution de fonctions
Pour l’étape du moteur d’exécution des fonctions React, définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du système. Placez l’état avec le composant qui gère la mutation. Mettre tout dans un stockage global rend les erreurs de synchronisation plus difficiles à détecter.
Component(props) → JSX
Section 2 : Pourquoi vos composants se rérenderont plus souvent que vous ne le pensez
Pour la section 2 « Pourquoi votre étape », définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Placez l’état au même endroit que le composant responsable de la mutation. Mettre tout en un stockage global rend les erreurs liées aux délais plus difficiles à détecter. Pour la section 2 « Pourquoi votre étape », définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définites des vérifications de succès et refusez les terminations partielles silencieuses.
1. Objets et fonctions en ligne de texte
Lors de la phase des 1 Objets et fonctions en ligne de texte, notez d’abord le contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Enregistrez les temps d’exécution ainsi que le coût en tokens ou en requêtes à côté des résultats fonctionnels. Une visibilité précoce du coût évite des factures inattendues lorsque le processus passe de l’environnement de démonstration à des environnements partagés. Considérez les effets comme une synchronisation avec le monde extérieur, et non comme un substitut aux valeurs dérivées lors du rendu.
<MyComponent options={{ theme: "dark" }} />
{} !== {}
onClick={() => doSomething()}
2. État soulevé trop haut
Lorsque vous travaillez sur l’étape 2 State Lifted Too, notez d’abord le contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de maintenir l’honnêteté des modifications ultérieures du code. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les flags fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du système. Considérez les effets comme une synchronisation avec le monde extérieur, et non comme un substitut aux valeurs dérivées lors du rendu.
3. État dérivé stocké en tant qu’état
Lors du traitement de l’étape 3 « État dérivé stocké », notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’améliorations apportées ultérieurement. Considérez les effets comme une synchronisation avec le monde extérieur, et non comme un substitut aux valeurs dérivées lors du rendu. Lors du traitement de l’étape 3 « État dérivé stocké », notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Traitez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définez des contrôles de succès et refusez les terminations partielles silencieuses.
const [filtered, setFiltered] = useState([]);
useEffect(() => {
setFiltered(items.filter(...));
}, [items]);
Section 3 : La règle qui a tout changé pour moi
La phase « Section 3 : La règle » fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un transcript parfait, un cas d’échec et la note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le parcours passe de l’environnement de démonstration aux environnements partagés. Gardez les tâches de rendu peu coûteuses et reportez les calculs onéreux à la mise en mémoire uniquement après avoir effectué des mesures ; une mise en mémoire prématurée peut cacher des bugs liés à des données obsolètes.
Section 4 : Les 4 niveaux de contrôle du re-render dans React
La section 4 – les 4 étapes – fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemple réussi, un cas d’échec et la note de réversion avant d’élargir le périmètre. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Maintenez le coût des opérations de rendu faible et reportez les calculs coûteux à la mise en mémoire uniquement après avoir effectué des mesures. Une mise en mémoire prématurée peut cacher des erreurs liées à des données obsolètes.
Niveau 1 : Optimisation structurelle (le plus important)
La phase d’optimisation structurelle de niveau 1 fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Maintenez les coûts de rendu faibles et reportez les calculs coûteux à la mise en mémoire uniquement après avoir effectué des mesures. Une mise en mémoire prématurée peut cacher des bugs liés à des données obsolètes. La phase d’optimisation structurelle de niveau 1 fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Considérez cette phase comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définez des critères de succès et refusez toute complétion partielle silencieuse.
Niveau 2 : Mémorisation (lorsque c’est nécessaire)
Pour l’étape de mémorisation de niveau 2, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le parcours passe d’un environnement de démonstration à des environnements partagés. Placez l’état au même endroit que le composant responsable de la mutation ; placer tout dans un stockage global rend les erreurs liées aux temps d’exécution plus difficiles à détecter.
Niveau 3 : Stabilité référentielle
Pour l’étape de stabilité référentielle de niveau 3, définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du système. Placez l’état au même endroit que le composant responsable de la mutation. Mettre tout dans un stockage global rend les erreurs liées aux délais plus difficiles à détecter.
const handler = () => doSomething();
const handler = useCallback(() => {
doSomething();
}, []);
const config = useMemo(() => ({
theme: "dark"
}), []);
Niveau 4 : Isolation architecturale
Pour l’étape d’Isolation architecturale de niveau 4, définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Colocalisez l’état avec le composant qui gère la mutation. Mettre tout en un stockage global rend les erreurs de synchronisation plus difficiles à détecter. Pour l’étape d’Isolation architecturale de niveau 4, définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Nommez les artefacts, définissez des vérifications de succès et refusez toute complétion partielle silencieuse.
Section 5 : React.memo — L’optimisation la plus mal utilisée
Lorsque vous travaillez sur l’étape React memo de la Section 5, notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Enregistrez les temps d’exécution ainsi que le coût en tokens ou en requêtes à côté des résultats fonctionnels. Une visibilité précoce du coût évite des factures inattendues lorsque le projet passe d’un environnement de démonstration à des environnements partagés. Considérez les effets comme une synchronisation avec le monde extérieur, et non comme un substitut aux valeurs dérivées lors du rendu.
Lorsque React.memo ne fait RIEN
Lorsque vous travaillez sur l’étape « Quand React.memo fonctionne », notez d’abord le contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Gardez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les flags fonctionnels doivent être regroupés en un seul endroit que les administrateurs peuvent auditer sans devoir lire l’ensemble du système. Considérez les effets comme une synchronisation avec le monde extérieur, et non comme un substitut aux valeurs dérivées lors du rendu.
Quand React.memo est utile
Lorsque vous travaillez sur l’étape « When React memo Shines », notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’honnêteté des modifications ultérieures du code. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’améliorations apportées ultérieurement. Considérez les effets comme une synchronisation avec le monde extérieur, et non comme un substitut aux valeurs dérivées lors du rendu. Lorsque vous travaillez sur l’étape « When React memo Shines », notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’honnêteté des modifications ultérieures du code. Traitez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définites des vérifications de succès et refusez les terminations partielles silencieuses.
Section 6 : Le piège de useCallback
La section 6, concernant l’étape useCallback, fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemple réussi, un cas d’échec ainsi que la note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts permet d’éviter des factures inattendues lorsque le chemin passe de l’environnement de démonstration à des environnements partagés. Gardez les opérations de rendu peu coûteuses et reportez les calculs onéreux à l’après-mémorisation, uniquement après avoir effectué des mesures. Une mémorisation prématurée peut cacher des bugs liés à des props obsolètes.
const handleClick = useCallback(() => {
setCount(c => c + 1);
}, []);
Section 7 : Le coût caché du contexte
La section 7 « Le stade caché » fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un transcript doré, un cas d’échec et la note de rollback avant d’élargir le périmètre. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les stocks de secrets et les flags fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du graphe. Maintenez les tâches de rendu peu coûteuses et reportez les calculs coûteux à la mise en mémoire uniquement après avoir effectué des mesures. Une mise en mémoire prématurée peut cacher des bugs liés à des propriétés obsolètes.
Mauvais :
Le stade « Bad » fonctionne le mieux lorsqu’il est considéré comme une surface mesurable. Capturez un transcript parfait, un cas d’échec et la note de rollback avant d’élargir le périmètre. Documentez ensemble le parcours réussi et le parcours de récupération. Les tentatives répétées, les contrôles humains et le traitement des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Gardez les opérations de rendu peu coûteuses et reportez les calculs onéreux à la mise en mémoire uniquement après avoir effectué des mesures ; une mise en mémoire prématurée peut cacher des bugs liés à des données obsolètes.
<AuthContext.Provider value={{ user, theme }}>
Mieux :
Le stade « Better » fonctionne le mieux lorsqu’il est considéré comme une surface mesurable. Capturez un transcript parfait, un cas d’échec et la note de réversion avant d’élargir le périmètre. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’erreur doit pointer vers une seule responsabilité plutôt qu’un processus embrouillé. Maintenez les tâches de rendu peu coûteuses et reportez les calculs onéreux à la mise en mémoire uniquement après avoir effectué des mesures. Une mise en mémoire prématurée peut cacher des bugs liés à des données obsolètes.
<UserContext />
<ThemeContext />
Section 8 : Listes, clés et l’illusion de stabilité
La phase des listes de Section 8 fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un transcript parfait, un cas d’échec et la note de réversion avant d’élargir le périmètre. Considérez cette phase comme un contrat entre les entrées et les sorties validées. Nommez les artefacts, définites des critères de succès et refusez toute mise en œuvre partielle silencieuse. Maintenez les coûts de rendu faibles et reportez les calculs coûteux à la mise en mémoire uniquement après avoir effectué des mesures. Une mise en mémoire prématurée peut cacher des bugs liés à des données obsolètes.
items.map((item, i) => <Row key={i} />)
items.map(item => <Row key={item.id} />)
Section 9 : la liste de contrôle des performances personnelles
La section 9, relative à l’étape personnelle, fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemple réussi, un cas d’échec ainsi que la note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le processus passe de l’environnement de démonstration à des environnements partagés. Gardez les tâches de rendu peu coûteuses et reportez les calculs coûteux à l’après-mémoisation, uniquement après avoir effectué des mesures. Une mémoisation prématurée peut cacher des bugs liés à des données obsolètes.
Section 10 : Le grand changement de mentalité
La section 10 « Le Grand Échiquier » fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemple réussi, un cas d’échec et la note de réversion avant d’élargir le périmètre. Gardez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Maintenez le coût des opérations de rendu faible et reportez les calculs coûteux à la mise en mémoire uniquement après avoir effectué des mesures. Une mise en mémoire prématurée peut cacher des erreurs liées à des données obsolètes.
Pensées finales : Le véritable secret
Conclusions finales : l’étape Real fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Documentez ensemble le parcours réussi et le parcours de récupération. Les tentatives répétées, les contrôles humains et le traitement des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Maintenez les coûts de rendu faibles et reportez les calculs coûteux à l’après-mémoïsation, uniquement après avoir effectué des mesures. Une mémoïsation prématurée peut cacher des bugs liés à des données obsolètes. Conclusions finales : l’étape Real fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définites des critères de succès et refusez toute complétion partielle silencieuse.
Performance et optimisation de React
Pour l’étape d’optimisation des performances de React, définissez les entrées, le responsable de l’étape et les critères d’achèvement avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché.