La performance de React au-delà des memo manuellement placés : structure et planification
Conseils de l’époque des compilateurs : placer les états ensemble, séparer le travail urgent, envoyer moins de JS, puis mémoriser les points chauds mesurés.
Pendant des années, les conseils concernant les performances de React consistaient à envelopper tout le code dans des API memo :
const value = useMemo(() => expensiveCalculation(data), [data]);
const handleClick = useCallback(() => {
doSomething(id);
}, [id]);export default React.memo(Component);
function ProductList({ products, onSelect }) {
const processed = useMemo(
() => processProducts(products),
[products]
);
const handleSelect = useCallback(
(id) => onSelect(id),
[onSelect]
); return (
<List
products={processed}
onSelect={handleSelect}
/>
);
}
App
│
├── Header
├── Sidebar
├── Search
├── ProductList
└── Footer
function App() {
const [query, setQuery] = useState("");
// large component tree
}
App
│
├── Header
├── Sidebar
├── Search
│ └── query state
├── ProductList
└── Footer
const [query, setQuery] = useState("");
const [isPending, startTransition] = useTransition();
function handleChange(event) {
const value = event.target.value; setQuery(value); startTransition(() => {
setSearchResults(filterProducts(value));
});
}
User input
│
├── urgent ───────► keep UI responsive
│
└── non-urgent ───► transition
const AnalyticsDashboard = lazy(
() => import("./AnalyticsDashboard")
);
Initial JavaScript
│
▼
┌─────────────────────┐
│ Everything │
│ Dashboard │
│ Analytics │
│ Editor │
│ Admin │
└─────────────────────┘
Initial load
│
├── Core UI
│
└── Later
├── Analytics
├── Editor
└── Admin
"This component renders often."
│
▼
Add useMemo
"This component renders often."
│
▼
Why?
│
┌──────┼───────────┐
▼ ▼ ▼
State Expensive Large
flow work subtree
│ │ │
▼ ▼ ▼
Colocate Optimize Restructure
1. Measure
↓
2. Find the expensive work
↓
3. Fix component architecture
↓
4. Reduce unnecessary JavaScript
↓
5. Prioritize updates correctly
↓
6. Let React Compiler handle memoization
↓
7. Manually optimize only when evidence says you should
La mémorisation seule ne résout pas les problèmes de lenteur des applications. Un arbre parfaitement mémorisé peut encore souffrir d’un état trop volumineux, de mises à jour urgentes effectuant des tâches non urgentes, ou d’un JavaScript lourd sur le thread principal.
Le compilateur React change la pratique par défaut
Le compilateur automatise de nombreux emplacements de mémorisation. Cela permet d’orienter les efforts des développeurs vers la structure et le planification, plutôt que d’insérer manuellement des useMemo partout.
Tout d’abord : placer l’état près de l’endroit où il est utilisé
Un état de haut niveau dans l’arbre rérendu à nouveau les sous-arbres importants. Placez l’état avec les feuilles qui en ont besoin ; ne le mettez à jour qu’en cas de nécessité liée au partage.
Deuxièmement : ne faites pas en sorte que les mises à jour urgentes effectuent des tâches non urgentes
Gardez la saisie et les animations réactives. Reportez les tâches non urgentes grâce à des transitions ou à des valeurs différées, afin que les frappes de touche ne soient pas bloquées par des filtres coûteux.
Troisièmement : examinez le JavaScript que vous envoyez
Les boucles de synchronisation volumineuses, les formatteurs coûteux et les listes sans limite dominent avant même que le mécanisme de conciliation de React ne s’en mêle. Analysez le JavaScript en profondeur, et non seulement ce que montrent les outils React DevTools.
Alors, quand devriez-vous utiliser useMemo ?
Ce hook reste utile pour assurer la stabilité des références entre les enfants qui ne transmettent pas correctement leurs props, ainsi que pour des calculs purs vraiment coûteux — après en avoir mesuré l’impact. Ce n’est pas une solution par défaut à appliquer à toutes les valeurs.
La nouvelle mentalité de performance chez React
Structure → planification → envoi avec moins de JS → puis mémorisation microscopique des points critiques. La mémorisation assistée par le compilateur est un outil d’aide, pas un substitut à la conception.
Ajoutez un budget de performance aux propositions de modification : temps nécessaire pour la prochaine mise à jour graphique du formulaire principal, ainsi qu’un aperçu du profilur de React pour le parcours connu pour être gourmand en ressources.
Les listes doivent d’abord être virtualisées avant de mémoriser chaque ligne. La mémorisation après le chargement de 10 000 lignes reste inefficace.
Ajoutez un budget de performance aux propositions de modification : temps nécessaire pour la prochaine mise à jour graphique du formulaire principal, ainsi qu’un aperçu du profilur de React pour le parcours connu pour être gourmand en ressources.
Les listes doivent d’abord être virtualisées avant de mémoriser chaque ligne. La mémorisation après le chargement de 10 000 lignes reste inefficace.
Ajoutez un budget de performance aux propositions de modification : temps nécessaire pour la prochaine mise à jour graphique du formulaire principal, ainsi qu’un aperçu du profilur de React pour le parcours connu pour être gourmand en ressources.
Les listes doivent d’abord être virtualisées avant de mémoriser chaque ligne. La mémorisation après le chargement de 10 000 lignes reste inefficace.
Ajouter un budget de performance aux PR : temps nécessaire pour la prochaine mise à jour graphique du formulaire principal, ainsi qu’un instantané du profilurateur React pour la route connue pour être gourmande en ressources.
Les listes doivent d’abord être virtualisées avant de pouvoir mémoriser chaque ligne. La mise en mémoire des données lors du chargement de 10 000 lignes reste inefficace.
Ajouter un budget de performance aux PR : temps nécessaire pour la prochaine mise à jour graphique du formulaire principal, ainsi qu’un instantané du profilurateur React pour la route connue pour être gourmande en ressources.
Les listes doivent d’abord être virtualisées avant de pouvoir mémoriser chaque ligne. La mise en mémoire des données lors du chargement de 10 000 lignes reste inefficace.
Ajouter un budget de performance aux PR : temps nécessaire pour la prochaine mise à jour graphique du formulaire principal, ainsi qu’un instantané du profilurateur React pour la route connue pour être gourmande en ressources.
Les listes doivent d’abord être virtualisées avant de pouvoir mémoriser chaque ligne. La mise en mémoire des données lors du chargement de 10 000 lignes reste inefficace.