Avec la sortie de React 16.8, il existe de nombreux hooks utiles que vous pouvez désormais utiliser dans vos applications React. L'un des hooks intégrés qui a été introduit dans la version 16.8 est useMemo. Ce hook a le potentiel d'améliorer les performances de votre application.

Cet article explore le fonctionnement du re-rendu dans React, pourquoi c'est une considération importante pour les applications React, et comment le hook useMemo peut l'exploiter pour créer une augmentation des performances dans vos applications. Vous apprendrez également quand useMemo peut causer des problÚmes de performance.

ÉgalitĂ© rĂ©fĂ©rentielle et opĂ©rations coĂ»teuses

Il y a deux problÚmes que useMemo cherche à résoudre :

  • l'Ă©galitĂ© rĂ©fĂ©rentielle
  • les opĂ©rations coĂ»teuses en termes de calcul

Dans le cycle de vie d'un composant, React refait le rendu du composant lorsqu'une mise à jour est effectuée. Lorsque React vérifie les modifications apportées à un composant, il peut détecter un changement involontaire ou inattendu en raison de la façon dont JavaScript gÚre les comparaisons d'égalité et superficielles. Ce changement dans l'application React entraßnera un nouveau rendu inutile.

De plus, si ce nouveau rendu est une opĂ©ration coĂ»teuse, comme une longue boucle for, cela peut nuire aux performances. Les opĂ©rations onĂ©reuses peuvent ĂȘtre coĂ»teuses en temps, en mĂ©moire ou en traitement. En plus des problĂšmes techniques potentiels, cela peut conduire Ă  une mauvaise expĂ©rience utilisateur.

Si une partie se rend Ă  nouveau, elle rend Ă  nouveau l'ensemble de l'arbre des composants.

Ainsi, React a lancé l'idée du mémo pour résoudre ce problÚme.

Qu'est-ce que la Memoization ?

La mĂ©morisation est une technique d'optimisation qui consiste Ă  passer une fonction complexe Ă  mĂ©moriser. Dans la mĂ©morisation, le rĂ©sultat est "mĂ©morisĂ©" lorsque les mĂȘmes paramĂštres sont transmis par la suite.

Si nous avons une fonction qui calcule 1 + 1, elle retournera 2. Mais si elle utilise la mémorisation, la prochaine fois que nous passerons des 1 dans la fonction, elle ne les additionnera pas ; elle se souviendra simplement que la réponse est 2 sans exécuter la fonction d'addition.

Dans la documentation officielle de React, la signature de useMemo ressemble Ă  ceci :

const memoizedValue = React.useMemo(() => computeExpensiveValue(a, b), [a, b]);

useMemo prend en paramÚtre une fonction et un tableau de dépendances.

Les dĂ©pendances agissent comme des arguments dans une fonction. La liste des dĂ©pendances est l'Ă©lĂ©ment que useMemo surveille : s'il n'y a pas de changement, le rĂ©sultat de la fonction restera le mĂȘme. Sinon, il rĂ©exĂ©cutera la fonction. S'ils ne changent pas, peu importe que tout notre composant soit modifiĂ©, la fonction ne sera pas rĂ©-exĂ©cutĂ©e mais retournera le rĂ©sultat stockĂ©. Cela peut ĂȘtre optimal si la fonction enveloppĂ©e est grande et coĂ»teuse. C'est l'utilisation principale de useMemo.

Exemple d'utilisation de useMemo ?

Voici un exemple abstrait d'utilisation de useMemo pour un tableau d'éléments qui utilise deux fonctions coûteuses en termes de calcul :

const List = React.useMemo(
  () =>
    listOfItems.map((item) => ({
      ...item,
      itemProp1: expensiveFunction(props.first),
      itemProp2: anotherPriceyFunction(props.second),
    })),
  [listOfItems]
);

Dans l'exemple ci-dessus, la fonction useMemo s'exécuterait au premier rendu. Elle bloquerait le thread jusqu'à ce que les fonctions coûteuses soient terminées, car useMemo s'exécute lors du premier rendu.

Au départ, cela n'aura pas l'air aussi propre que useEffect, puisque useEffect peut rendre une roue de chargement jusqu'à ce que les fonctions coûteuses se terminent et que les effets se déclenchent.

Cependant, dans les rendus suivants, les fonctions coĂ»teuses n'auront pas besoin d'ĂȘtre exĂ©cutĂ©es Ă  nouveau tant que listOfItems ne change pas. useMemo se "souviendra" de la valeur de retour de chaque fonction.

Ces fonctions coĂ»teuses donneraient l'impression d'ĂȘtre rendues instantanĂ©ment. C'est idĂ©al si vous avez une ou deux fonctions coĂ»teuses et synchrones.

Quand utiliser useMemo ?

Écrivez d'abord le code, puis revisitez-le pour voir si vous pouvez l'optimiser. Si vous implĂ©mentez useMemo trop souvent dans une application, cela peut nuire aux performances.

Lorsque vous envisagez de mettre en Ɠuvre useMemo, vous pouvez utiliser des outils de profilage pour identifier les problĂšmes de performance coĂ»teux. Un problĂšme coĂ»teux signifie que l'application utilise beaucoup de ressources (comme la mĂ©moire). Si vous dĂ©finissez un bon nombre de variables dans une fonction au rendu, il est logique de mĂ©moriser avec useMemo.

Utiliser le bon hook pour le travail

En plus de useMemo, il existe Ă©galement useCallback, useRef et useEffect.

Le hook useCallback est similaire à useMemo, mais il renvoie une fonction mémorisée, alors que useMemo a une fonction qui renvoie une valeur.

Si votre tableau de dépendances n'est pas fourni, il n'y a aucune possibilité de mémorisation, et il calculera une nouvelle valeur à chaque rendu. Vous pouvez utiliser le hook useRef dans ce cas. L'avantage de useMemo par rapport à useRef est une re-mémorisation si les dépendances changent.

Vous ne voudrez pas que useMemo déclenche des effets secondaires ou des appels asynchrones. Dans ces cas, vous devriez utiliser useEffect.

Conclusion

Cet article a exploré le hook useMemo et quand il est approprié de l'utiliser dans une application React.

useMemo peut améliorer les performances d'une application en "mémorisant" les fonctions coûteuses et en évitant un nouveau rendu à chaque fois qu'un changement est apporté à l'application.

Bien que les performances puissent ĂȘtre amĂ©liorĂ©es en utilisant ce hook, il peut Ă©galement ralentir votre application si vous l'utilisez trop. Plus vous utilisez ce crochet, plus votre application doit allouer de la mĂ©moire.