useMemo scheint zu funktionieren, als sollte es "den gleichen Wert" zwischenspeichern, aber React vergleicht nicht die geschäftliche Bedeutung. Es vergleicht die Identität der Abhängigkeiten. Wenn ein Array oder Objekt bei jedem Rendern neu erstellt wird, erkennt useMemo eine neue Abhängigkeit und berechnet trotzdem neu.
Das ist der Grund, warum viele Memoisierungsversuche nichts Messbares bewirken.
Der häufige Fehler
Das sieht korrekt aus:
const sorted = useMemo(() => expensiveSort(items), [items]);
Aber wenn das übergeordnete Element items jedes Mal neu erstellt:
<Dashboard items={[...rawItems]} />
bleibt die Memoisierung nie wirklich bestehen. Das Kind hat recht. Der Eingang ist instabil.
Wo useMemo tatsächlich lohnt
Memoisierung ist in der Regel sinnvoll, wenn eines dieser Dinge zutrifft:
- die abgeleitete Berechnung ist kostspielig
- der Wert wird in einen memoisierten Teilbaum übergeben
- referentielle Stabilität beeinflusst das Rendering-Verhalten nachgelagerter Komponenten
Es ist meist nicht lohnenswert für winzige Berechnungen, die nur existieren, um den Code optimiert erscheinen zu lassen.
Das bessere mentale Modell
Gute Memoisierung beginnt upstream. Stabilisieren Sie zunächst die Eingaben oder vermeiden Sie es, Datenstrukturen unnötig neu zu erstellen. Danach profilieren. Fügen Sie useMemo nur dort hinzu, wo es die tatsächliche Arbeitslast verringert.
Das ist umso wichtiger, da sich die React-Tools weiterentwickeln. Der React-Compiler kann einige Optimierungspfade automatisieren, beseitigt jedoch nicht die Notwendigkeit, Identität und Datenfluss zu verstehen.
Praktische Regel
Fügen Sie useMemo nicht hinzu, weil ein Wert "abgeleitet" ist. Fügen Sie es hinzu, weil das Profiling zeigt, dass die Neuberechnung oder die Kosten für das nachgelagerte Neurendern es wert sind, gegen die zusätzliche Komplexität eingetauscht zu werden.
Weitere Lektüre