La mémorisation est une technique d'optimisation, similaire à la mise en cache. Cela fonctionne en stockant les résultats précédents d'un appel de fonction et en utilisant ces résultats la prochaine fois que la fonction s'exécute. Il est particulièrement utile dans les applications gourmandes en calcul qui répètent les appels de fonction sur les mêmes paramètres.

Vous pouvez utiliser la mémorisation en JavaScript brut et également dans React, de différentes manières.

Mémoïsation en JavaScript

Pour mémoriser une fonction en JavaScript, vous devez stocker les résultats de cette fonction dans un cache. Le cache peut être un objet avec les arguments comme clés et les résultats comme valeurs.

Lorsque vous appelez cette fonction, elle vérifie d'abord si le résultat est présent dans le cache avant de s'exécuter. Si c'est le cas, il renvoie les résultats mis en cache. Sinon, il s'exécute.

Considérez cette fonction :

fonctioncarré(nombre) {
revenir nombre * nombre
}

La fonction prend un argument et renvoie son carré.

instagram viewer

Pour exécuter la fonction, appelez-la avec un numéro comme celui-ci :

carré(5) // 25

Avec 5 comme argument, square() fonctionnera assez rapidement. Cependant, si vous deviez calculer le carré de 70 000, il y aurait un retard notable. Pas de beaucoup mais un retard quand même. Maintenant, si vous deviez appeler la fonction plusieurs fois et dépasser 70 000, vous subiriez un retard à chaque appel.

Vous pouvez éliminer ce retard en utilisant la mémorisation.

constante memoizedCarré = () => {
laisser cache = {};
revenir (num) => {
si (num dans cache) {
console.log('Réutilisation de la valeur mise en cache');
revenir cache[nombre];
} autre {
console.log('Calcul du résultat');
laisser résultat = nombre * nombre ;

// cache la NouveaurésultatévaluerpourSuivanttemps
cache[nombre] = résultat;
revenir résultat;
}
}
}

Dans cet exemple, la fonction vérifie si elle a calculé le résultat avant, en vérifiant s'il existe dans l'objet cache. Si c'est le cas, il renvoie la valeur déjà calculée.

Lorsque la fonction reçoit un nouveau nombre, elle calcule une nouvelle valeur et stocke les résultats dans le cache avant de revenir.

Encore une fois, cet exemple est assez simple, mais il explique comment la mémorisation fonctionnerait pour améliorer les performances d'un programme.

Vous ne devez mémoriser que des fonctions pures. Ces fonctions renvoient le même résultat lorsque vous transmettez les mêmes arguments. Si vous utilisez la mémorisation sur des fonctions impures, vous n'améliorerez pas les performances mais augmenterez votre surcharge. C'est parce que vous choisissez la vitesse plutôt que la mémoire chaque fois que vous mémorisez une fonction.

Mémoïsation dans React

Si vous cherchez à optimiser les composants React, React fournit une mémorisation via le crochet useMemo(), React.memo et useCallBack().

Utilisation de useMemo()

useMemo() est un Crochet de réaction qui accepte une fonction et un tableau de dépendances.

constante memoizedValue = useMemo(() => computeExpensiveValue (a, b), [a, b]);

Il mémorise la valeur renvoyée par cette fonction. Les valeurs du tableau de dépendance dictent quand la fonction est exécutée. Ce n'est que lorsqu'ils changent que la fonction est exécutée à nouveau.

Par exemple, le composant App suivant a une valeur mémorisée appelée result.

importer { utiliserMémo } de "réagir"
fonctionApplication(évaluer) {
constante carré = (valeur) => {
revenir valeur * valeur
}
constante result = useMemo(
() => carré (valeur),
[ évaluer ]
);
revenir (
<div>{résultat (5)}</div>
)
}

Le composant App appelle square() à chaque rendu. Les performances se dégraderont si le composant App est rendu plusieurs fois en raison de Réagissez les accessoires changement ou mise à jour d'état, surtout si la fonction square() est coûteuse.

Cependant, étant donné que useMemo() met en cache les valeurs renvoyées, la fonction carrée n'est pas exécutée à chaque nouveau rendu à moins que les arguments du tableau de dépendances ne changent.

Utilisation de React.memo()

React.memo() est un composant d'ordre supérieur qui accepte un composant React et une fonction comme arguments. La fonction détermine quand le composant doit être mis à jour.

La fonction est facultative et si elle n'est pas fournie, React.memo effectue une comparaison de copie superficielle des accessoires actuels du composant avec ses accessoires précédents. Si les accessoires sont différents, cela déclenche une mise à jour. Si les accessoires sont les mêmes, il ignore le nouveau rendu et réutilise les valeurs mémorisées.

La fonction facultative accepte les accessoires précédents et les accessoires suivants comme arguments. Vous pouvez ensuite comparer explicitement ces accessoires pour décider de mettre à jour ou non le composant.

Réagir.note(Composant, [areEqual (prevProps, nextProps)])

Regardons d'abord un exemple sans l'argument optionnel de la fonction. Vous trouverez ci-dessous un composant appelé Commentaires qui accepte les accessoires de nom et d'e-mail.

fonctioncommentaires ({nom, commentaire, j'aime}) {
revenir (
<div>
<p>{Nom}</p>
<p>{commentaire}</p>
<p>{aime}</p>
</div>
)
}

Le composant de commentaires mémorisés sera entouré de React.memo comme ceci :

constante MemoizedComment = React.memo (Commentaire)

Vous pouvez l'appeler puis l'appeler comme n'importe quel autre composant React.

<Nom du commentaire mémoisé="Marie" commentaire="La mémorisation est super" j'aime=1/>

Si vous souhaitez effectuer vous-même la comparaison des accessoires, transmettez la fonction suivante à React.memo en tant que deuxième argument.

importer Réagir de "réagir"
fonctioncheckCommentProps(prevProps, nextProps) {
revenir prevProps.name nextProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes
}

constante MemoizedComment = React.memo (Commentaires, checkCommentProps)

Si checkProfileProps renvoie true, le composant n'est pas mis à jour. Sinon, il est restitué.

La fonction personnalisée est utile lorsque vous souhaitez personnaliser le nouveau rendu. Par exemple, vous pouvez l'utiliser pour mettre à jour le composant Commentaires uniquement lorsque le nombre de likes change.

Contrairement au crochet useMemo() qui mémorise uniquement la valeur renvoyée d'une fonction, React.memo mémorise toute la fonction.

Utilisez React.memo uniquement pour les composants purs. De plus, pour réduire les coûts de comparaison, ne mémorisez que les composants dont les accessoires changent souvent.

Utilisation de useCallBack()

Vous pouvez utiliser le hook useCallBack() pour mémoriser composants fonctionnels.

constante memoizedCallback = useCallback(
() => {
faire quelque chose (a, b);
},
[un B],
);

La fonction est mise à jour uniquement lorsque les valeurs du tableau de dépendances changent. Le crochet fonctionne comme le rappel useMemo(), mais il mémorise le composant de la fonction entre les rendus au lieu de mémoriser les valeurs.

Considérez l'exemple suivant d'une fonction mémorisée qui appelle une API.

importer { useCallback, useEffect } de "réagir";
constante Composant = () => {
constante getData = useCallback(() => {
console.log('appeler une API');
}, []);
useEffet(() => {
getData();
}, [obtenir des données]);
};

La fonction getData() appelée dans useEffect ne sera appelée à nouveau que lorsque la valeur getData changera.

Faut-il mémoriser ?

Dans ce didacticiel, vous avez appris ce qu'est la mémorisation, ses avantages et comment l'implémenter dans JavaScript et React. Cependant, vous devez savoir que React est déjà rapide. Dans la plupart des cas, la mémorisation des composants ou des valeurs ajoute des coûts de comparaison et n'améliore pas les performances. Pour cette raison, ne mémorisez que des composants coûteux.

React 18 a également introduit de nouveaux crochets comme useId, useTransition et useInsertionEffect. Vous pouvez les utiliser pour améliorer les performances et l'expérience utilisateur des applications React.