Lire les traces de performance de React dans les outils de développement de Chrome pour identifier les rendus lents
Découvrez comment le planificateur, les composants et le serveur ajoutés dans React 19.2 permettent de déterminer où passe le temps lors d’une interaction lente, ainsi qu’un flux de travail « enregistrer-problème-enregistrer » pour y remédier.
Sources: Stop Guessing Why React Is Slow. Use the Performance Timeline.
Lorsqu’une interaction avec React semble lente, on a tendance à ajouter useMemo, useCallback et React.memo en espérant que cela résoudra le problème. Souvent, la page reste lente, car personne n’a mesuré ce qui consomme du temps. React 19.2 a introduit les Performance Tracks, qui enregistrent les activités de React dans la timeline des performances du navigateur ; voici ce que montre chaque track et comment transformer une enregistrement en solution ciblée.
Pourquoi la timeline classique était difficile à lire
En enregistrant une interaction lente dans le panneau Performance des Chrome DevTools sur une application sans ces tracks, le thread principal ressemble généralement à ceci :
JavaScript
████████████████████
██████████
███
████████████
JavaScript est clairement occupé, mais quel composant en est responsable, quelle mise à jour a déclenché le rendu, la page attendait-elle une réponse du réseau, un Effect a-t-il dominé le processus, et React a-t-il rendu juste au moment où l’utilisateur attendait une réponse immédiate ? La vue générale vous oblige à reconstituer ces informations à partir des noms de fonctions. Les pistes React fournissent le contexte manquant.
Ce que les pistes React ajoutent
React propose des pistes dédiées pour trois domaines :
Scheduler
Components
Server
Elles se trouvent à côté des flux habituels du navigateur, de sorte qu’un seul trace peut être lu approximativement comme ceci :
USER CLICK
│
▼
┌─────────────────────────────┐
│ React Scheduler │
│ Blocking → Render → Commit │
├─────────────────────────────┤
│ React Components │
│ Dashboard │
│ ├─ Header │
│ ├─ DataTable ← expensive │
│ └─ Chart │
├─────────────────────────────┤
│ Network / JavaScript │
└─────────────────────────────┘
La valeur réside dans la corrélation : l’activité de React et l’activité du navigateur apparaissent sur une même axe temporel commun.
Scheduler : pourquoi ce travail a-t-il été exécuté maintenant ?
React ne traite pas chaque mise à jour de la même manière. Le planificateur sépare les tâches en fonction de leur priorité, avec des catégories telles que Blocking, Transition, Suspense et Idle, et il identifie les phases de chaque mise à jour : Update, Render, Commit, ainsi que tous les effets restants.
Cela permet de répondre à des questions comme « pourquoi y a-t-il un retard lors de la saisie dans ce champ ? ». Le suivi peut montrer qu’une touche appuyée a déclenché un rendu synchrone lourd dans la catégorie Blocking. Ou bien il peut indiquer que le travail coûteux a déjà été correctement encadré dans une transition, ce qui oriente vers une autre source d’information. Dans tous les cas, on travaille sur des preuves plutôt que sur de l’intuition. Si les transitions et les priorités vous sont inconnues, le modèle sous-jacent à ces catégories est expliqué dans Understanding React Lanes.
Composants : qui a effectué le travail ?
Pour le débogage quotidien, c’est généralement la méthode la plus utile. Elle affiche sur un flamegraph combien de temps chaque composant a passé à rendre et à exécuter des effets, et pendant le développement, elle peut également mettre en évidence les propriétés modifiées ainsi que les mises à jour en cascade. Un résultat comme celui-ci est typique :
ProductPage 310ms
├── Header 12ms
├── Filters 18ms
├── DataTable 245ms ←
└── Footer 8ms
Plutôt que de se plaindre vaguement que React est lent, vous disposez maintenant d’une piste précise : DataTable a consommé la majeure partie du temps de rendu. Ensuite, vérifiez s’il affiche trop de lignes, recalcule les données à chaque passage ou reçoit de nouvelles propriétés de son parent à chaque fois.
Serveur : la page attend-elle vraiment React ?
Dans les applications utilisant des composants serveur React, les builds de développement affichent en plus les requêtes serveur et le travail des composants serveur sur la timeline. Cela révèle un diagnostic erroné fréquent :
Slow page
│
▼
Assume React render
│
X
│
▼
Actually waiting on:
getProducts()
│
▼
Database / API
Si le suivi montre que la page est inactive tandis que getProducts() attend une réponse de la base de données ou d’une API, la solution réside dans le chargement des données, comme l’utilisation du cache, les requêtes parallèles ou des requêtes plus efficaces ; envelopper les composants dans React.memo ne sera d’aucune aide. C’est précisément pour cette raison qu’il est nécessaire de disposer du calendrier complet d’exécution dans une seule vue.
Un flux de travail de débogage reproductible
Lorsqu’une interaction semble lente, suivez toujours la même séquence :
1. Reproduce the problem
↓
2. Open Performance
↓
3. Record the interaction
↓
4. Find the slow React work
↓
5. Inspect the component / phase
↓
6. Check network and browser work
↓
7. Fix the actual bottleneck
↓
8. Record again
Ne sautez pas l’étape finale. Enregistrez à nouveau dans les mêmes conditions et comparez. Une optimisation qui n’a jamais été mesurée à nouveau n’est qu’une hypothèse ; parfois, le deuxième suivi montre que la modification a simplement déplacé le coût ailleurs au lieu de l’éliminer.
Connaître les limites d’un suivi local
Les pistes de performance sont un outil d’aide au développement et à l’analyse. React indique que l’instrumentation ajoute une charge supplémentaire et qu’elle est désactivée par défaut dans les versions de production, tandis que les pistes serveur ne sont disponibles que pour les versions de développement. De plus, les versions de développement fonctionnent globalement plus lentement, il convient donc de se fier davantage aux proportions qu’aux chiffres absolus.
Cela signifie qu’un trace net sur votre machine ne prouve pas que les utilisateurs réels bénéficient d’une expérience rapide. La performance en production nécessite encore des données issues du terrain et une surveillance des utilisateurs réels. Les pistes répondent à une question plus restreinte mais très pratique : que fait l’application, étape par étape, lorsque vous reproduisez ce problème spécifique ?
Points clés
L’habitude la plus coûteuse en termes de performance n’est pas de choisir le mauvais point d’ancrage ; c’est d’optimiser avant de comprendre le problème. Une approche plus solide consiste à :
Slow interaction
│
▼
Measure
│
▼
Find the bottleneck
│
┌─────┼──────┐
▼ ▼ ▼
React Network Browser
│ │ │
▼ ▼ ▼
Fix Fix Fix
- Mesurez d’abord : les pistes facilitent l’enregistrement et la localisation du goulot d’étranglement.
- Utilisez la piste Planificateur pour comprendre les priorités et les phases, ainsi que la piste Composants pour identifier le sous-arbre coûteux.
- Vérifiez la piste Serveur et les canaux réseau avant de supposer que le rendu est en cause.
- Redémarrez l’enregistrement après chaque modification pour confirmer que le problème est résolu.
- Considérez les traces locales comme un outil de diagnostic, et fiez-vous aux données en temps réel pour connaître l’expérience des utilisateurs.
Ainsi formulé, le sujet passe de la question de savoir s’il faut ajouter useMemo à celle de savoir ce qui a réellement consommé ces 200 millisecondes, et c’est cette dernière question qui permet de trouver une solution concrète.