almessadi.
Retour à l'index

Les fuites de fermeture React proviennent généralement de callbacks à long terme_

Les fermetures deviennent un problème de mémoire lorsque des minuteurs, des écouteurs ou des abonnements les maintiennent en vie plus longtemps que le cycle de vie du composant prévu.

Publié20 novembre 2024
Temps de lecture9 min read

Les fermetures ne sont pas un problème de React. Elles sont de la JavaScript normale. Elles deviennent un problème de mémoire uniquement lorsqu'un autre système maintient un callback en vie après que le composant qui l'a créé aurait dû disparaître.

C'est pourquoi les mêmes bogues continuent de réapparaître sous différentes formes :

  • écouteurs d'événements
  • intervalles
  • abonnements
  • observateurs

Une forme typique de fuite

Le problème ressemble généralement à ceci :

useEffect(() => {
  function onResize() {
    setWidth(window.innerWidth);
  }

  window.addEventListener("resize", onResize);
}, []);

Si l'écouteur n'est jamais supprimé, le callback peut garder des références à l'état du composant et aux fonctions de mise à jour plus longtemps que prévu. Une fuite peut sembler petite. Une navigation répétée à travers le même écran peut la transformer en une montée constante de la consommation mémoire.

Le schéma correct maintient l'enregistrement et le nettoyage ensemble :

useEffect(() => {
  function onResize() {
    setWidth(window.innerWidth);
  }

  window.addEventListener("resize", onResize);
  return () => window.removeEventListener("resize", onResize);
}, []);

Ce qu'il faut inspecter dans les applications réelles

Lorsque la mémoire augmente après des changements de route ou de longues sessions, commencez par les callbacks à long terme qui capturent l'état du composant. La question est simple : qui détient encore cette fermeture ?

Cette enquête mène généralement à :

  • écouteurs de navigateur
  • abonnements de bibliothèque
  • observateurs non fermés
  • bus d'événements personnalisés

Meilleure règle d'ingénierie

Chaque fois qu'un effet enregistre un callback en dehors de React, écrivez le chemin de nettoyage dans le même effet avant de passer à autre chose. Cette habitude empêche plus de fuites que n'importe quelle session de profilage ultérieure.

Lectures supplémentaires