# useMemo et useCallback dans un bloc complexe : évitent-ils un nouveau rendu

> Ajouter useMemo ou useCallback sur un bloc devenu lent ne garantit rien à lui seul. Ce qui compte vraiment, c'est où porter cet effort, et où il ne sert à rien.

- Auteur : WordPress Développement
- Publié le : 2024-06-23
- Mis à jour le : 2026-09-30
- Catégorie : Blocs Gutenberg
- URL : https://www.wpmoderne.fr/blocs/usememo-usecallback-bloc-complexe-nouveau-rendu/

## L’essentiel

- useMemo évite un recalcul coûteux, pas un nouveau rendu en soi
- useCallback n'aide que si la fonction est comparée par référence ailleurs
- Mesurer avant d'optimiser, sous peine d'alourdir le code pour rien

Un bloc devenu perceptiblement lent dans l'éditeur : la réaction la plus fréquente consiste à parsemer le code de `useMemo` et `useCallback`, en espérant que cela règle le problème. Or ni l'un ni l'autre n'empêche, à lui seul, un composant de se re-rendre : ils évitent, sous certaines conditions précises, de refaire un calcul coûteux ou de recréer une fonction à chaque rendu. La nuance compte, car mal ciblée, cette optimisation alourdit le code sans gain mesurable.

## Ce que useMemo mémorise réellement

`useMemo` conserve le résultat d'un calcul entre deux rendus, tant que les valeurs listées dans son tableau de dépendances n'ont pas changé. Il est utile lorsque ce calcul est réellement coûteux, un tri ou un filtrage sur une liste de plusieurs centaines d'éléments, par exemple, exécuté à chaque rendu du composant alors que les données sources changent rarement.

```
const articlesTries = useMemo( () => {
	return [ ...articlesRecents ].sort( ( a, b ) =>
		a.titre.localeCompare( b.titre )
	);
}, [ articlesRecents ] );
```

Sur une liste de trois ou quatre éléments, ce même tri s'exécute en un temps négligeable, largement inférieur au coût du rendu React lui-même. Ajouter `useMemo` dans ce cas n'apporte rien de mesurable, tout en ajoutant une ligne de code et un tableau de dépendances de plus à maintenir correctement.

## Ce que useCallback mémorise, et pourquoi cela compte moins souvent qu'on ne le pense

`useCallback` conserve la même référence de fonction entre deux rendus, tant que ses dépendances n'ont pas changé. Ce mécanisme n'a d'effet perceptible que si cette référence est ensuite comparée quelque part, typiquement lorsqu'elle est transmise en propriété à un composant enfant enveloppé dans `memo()`, qui compare justement ses propriétés par référence pour décider s'il doit se re-rendre.

```
const ComposantEnfant = memo( function ComposantEnfant( { onSelection } ) {
	// se re-rendra uniquement si onSelection change de référence
	return <button onClick={ onSelection }>Sélectionner</button>;
} );

const gererSelection = useCallback( () => {
	setAttributes( { elementSelectionne: id } );
}, [ id ] );
```

> L'essentiel à retenir : useMemo évite un recalcul coûteux, pas un nouveau rendu en soi ; useCallback n'aide que si la fonction est comparée par référence ailleurs ; Mesurer avant d'optimiser, sous peine d'alourdir le code pour rien

Si le composant enfant n'est pas mémoïsé avec `memo()`, il se re-rendra de toute façon à chaque rendu du parent, que la fonction transmise change de référence ou non : `useCallback` devient alors inutile, puisque rien en aval n'exploite la stabilité de cette référence.

## Mesurer avant d'optimiser

1. Activer le profileur de React DevTools et enregistrer une séquence d'interactions représentative sur le bloc concerné.
2. Repérer les composants qui se re-rendent le plus fréquemment et le temps réellement passé dans chacun.
3. Identifier, parmi ces composants, ceux dont le rendu effectue un calcul coûteux ou transmettent des propriétés à des enfants mémoïsés.
4. N'appliquer `useMemo` ou `useCallback` que sur ces points précis, puis rejouer la même séquence pour vérifier le gain réel.

## Le cas où l'optimisation la plus efficace n'est ni l'un ni l'autre

Souvent, le vrai gain de performance sur un bloc complexe ne vient pas d'une mémoïsation de calcul ou de fonction, mais d'une meilleure structuration des sélecteurs `useSelect`, qui peuvent redéclencher un rendu à chaque changement d'un store entier si leur sélection n'est pas suffisamment précise. Réduire la portée de ces sélecteurs, avant même d'envisager `useMemo` ou `useCallback`, résout fréquemment le ralentissement observé sans ajouter la moindre ligne de mémoïsation.

- Vérifier d'abord la précision des sélecteurs `useSelect` utilisés dans le composant.
- Réserver `useMemo` aux calculs dont le coût est mesurablement significatif.
- Réserver `useCallback` aux fonctions transmises à des composants enfants réellement mémoïsés.

> Une règle simple à garder en tête : une optimisation qu'on ne peut pas mesurer n'en est pas une, c'est une supposition qui alourdit le code en échange d'un gain hypothétique.

## En résumé

useMemo et useCallback ne suppriment pas un rendu ; ils évitent, dans des conditions précises, un recalcul ou une recréation de fonction inutiles. Utilisés sans mesure préalable, ils ajoutent de la complexité sans garantie de gain. Profiler d'abord, cibler ensuite les points réellement coûteux, reste la seule méthode qui évite d'optimiser à l'aveugle un bloc devenu lent.
