Leçon 10 / 20

Mémoïser un calcul dérivé coûteux

25 min React — architecture, performance et accessibilité Gratuit

Objectif : Mettre en cache le total mensuel uniquement lorsque le profilage montre que son calcul est significatif.

Quand vous changez un filtre ou saisissez une dépense, React peut recalculer le récapitulatif mensuel. Si ce calcul parcourt beaucoup de données, il peut ralentir une interaction ; s’il est léger, l’optimiser peut au contraire ajouter de la complexité sans bénéfice perceptible. Vous allez vous servir de la mesure de référence établie dans la leçon précédente pour décider si une mémoïsation est justifiée.

Repérer le calcul à optimiser

Le total mensuel est une donnée dérivée : il est calculé à partir des dépenses et du mois sélectionné, sans devenir un état supplémentaire. Comme vous l’avez vu pour les sources de vérité, conserver également ce total dans un état imposerait de le synchroniser avec ses entrées. Ici, vous gardez le calcul dans le hook useRecapitulatifMensuel et envisagez de le mettre en cache seulement si le profilage révèle un coût notable.

Comparez des interactions reproductibles : ouvrez le récapitulatif, modifiez le mois, puis répétez l’opération avec une liste de dépenses représentative. Dans React DevTools Profiler, observez la durée de rendu du composant qui utilise le hook et vérifiez si le calcul du total contribue effectivement au temps mesuré. Une liste courte et une opération simple ne suffisent pas à justifier une optimisation préventive.

Mettre en cache le total mensuel

Dans le fichier du projet src/hooks/useRecapitulatifMensuel.ts, appliquez useMemo autour de l’agrégation déjà réalisée par le hook. L’exemple suivant montre un hook complet, avec des entrées explicites : une liste de dépenses et le mois au format AAAA-MM. Il suppose que le type Depense du projet expose date et montant ; adaptez uniquement les noms des propriétés si votre définition existante diffère.

Texte
import { useMemo } from "react";
import type { Depense } from "../types/depense";

type RecapitulatifMensuel = {
  totalMensuel: number;
  nombreDepenses: number;
};

export function useRecapitulatifMensuel(
  depenses: readonly Depense[],
  mois: string
): RecapitulatifMensuel {
  return useMemo(() => {
    const depensesDuMois = depenses.filter((depense) =>
      depense.date.startsWith(`${mois}-`)
    );

    const totalMensuel = depensesDuMois.reduce(
      (total, depense) => total + depense.montant,
      0
    );

    return {
      totalMensuel,
      nombreDepenses: depensesDuMois.length
    };
  }, [depenses, mois]);
}

Le callback transmis à useMemo regroupe le filtrage et l’addition ; sa valeur de retour contient le total et le nombre de dépenses du mois. Le hook réutilise cette valeur tant que les références de depenses et mois ne changent pas. Ces deux entrées figurent donc dans le tableau de dépendances : omettre l’une d’elles pourrait laisser le récapitulatif afficher un résultat périmé.

Vérifier le gain réel

Relancez le même scénario dans Profiler, avec une quantité de données et un environnement comparables à votre mesure initiale. Vérifiez que le résultat affiché reste identique, puis comparez le temps de rendu et la fluidité des interactions. Le cache ne supprime pas le coût lorsque les dépenses ou le mois changent : il évite seulement de refaire ce calcul lors d’un rendu où ces entrées sont inchangées.

Ne cherchez pas à obtenir une baisse dans chaque scénario : si la durée est déjà faible ou si le calcul s’exécute rarement, le bénéfice peut être négligeable. Conservez une note de la mesure avant et après, ainsi que du scénario testé. Si vous ne constatez pas d’amélioration utile, retirez useMemo et gardez le calcul simple ; la mémoïsation est un outil d’optimisation, pas une garantie de vitesse.

À retenir

  • Mesurez le calcul dans une interaction représentative avant de l’optimiser.
  • Gardez le total mensuel dérivé des dépenses et du mois, sans état dupliqué.
  • Avec useMemo, déclarez toutes les entrées qui déterminent le résultat.
  • Comparez les profils avant et après et retirez la mémoïsation sans gain pertinent.

Dans la prochaine leçon, vous stabiliserez les fonctions transmises aux composants enfants, après avoir identifié les cas où leur identité influence réellement les rendus.

Envie d'aller plus loin ?

Les cours Enovatic sont gratuits et le resteront. Si vous cherchez un accompagnement encadré, nos formations professionnelles sont animées par les mêmes formateurs.