Memoization ist eine Optimierungstechnik, ähnlich wie Caching. Es funktioniert, indem es die vorherigen Ergebnisse eines Funktionsaufrufs speichert und diese Ergebnisse verwendet, wenn die Funktion das nächste Mal ausgeführt wird. Es ist besonders nützlich in rechenintensiven Apps, die Funktionsaufrufe mit denselben Parametern wiederholen.
Sie können die Memoisierung in einfachem JavaScript und auch in React auf verschiedene Arten verwenden.
Memos in JavaScript
Um eine Funktion in JavaScript zu speichern, müssen Sie die Ergebnisse dieser Funktion in einem Cache speichern. Der Cache kann ein Objekt mit den Argumenten als Schlüssel und den Ergebnissen als Werte sein.
Wenn Sie diese Funktion aufrufen, prüft sie zunächst, ob das Ergebnis im Cache vorhanden ist, bevor sie ausgeführt wird. Wenn dies der Fall ist, werden die zwischengespeicherten Ergebnisse zurückgegeben. Andernfalls wird es ausgeführt.
Betrachten Sie diese Funktion:
FunktionQuadrat(Anzahl) {
Rückkehr num * num
}
Die Funktion nimmt ein Argument auf und gibt sein Quadrat zurück.
Um die Funktion auszuführen, rufen Sie sie mit einer Nummer wie dieser auf:
Quadrat(5) // 25
Mit 5 als Argument läuft square() ziemlich schnell. Wenn Sie jedoch das Quadrat von 70.000 berechnen würden, würde es eine spürbare Verzögerung geben. Nicht viel, aber dennoch eine Verzögerung. Wenn Sie nun die Funktion mehrmals aufrufen und 70.000 übergeben würden, würden Sie bei jedem Aufruf eine Verzögerung feststellen.
Sie können diese Verzögerung durch Memoization eliminieren.
konst memoizedSquare = () => {
Lassen Zwischenspeicher = {};
Rückkehr (Zahl) => {
wenn (Anzahl ein Zwischenspeicher) {
Konsole.log ('Zwischengespeicherten Wert wiederverwenden');
Rückkehr Zwischenspeicher[Anzahl];
} anders {
Konsole.log ('Rechenergebnis');
Lassen Ergebnis = Zahl * Zahl;
// Zwischenspeicher das NeuErgebnisWertzumnächsteZeit
Zwischenspeicher[Anzahl] = Ergebnis;
Rückkehr Ergebnis;
}
}
}
In diesem Beispiel prüft die Funktion, ob sie das Ergebnis vorher berechnet hat, indem sie prüft, ob es im Cache-Objekt vorhanden ist. Wenn dies der Fall ist, wird der bereits berechnete Wert zurückgegeben.
Wenn die Funktion eine neue Zahl erhält, berechnet sie einen neuen Wert und speichert die Ergebnisse im Cache, bevor sie zurückkehrt.
Auch dieses Beispiel ist ziemlich einfach, aber es erklärt, wie Memoisierung funktionieren würde, um die Leistung eines Programms zu verbessern.
Sie sollten nur reine Funktionen auswendig lernen. Diese Funktionen geben dasselbe Ergebnis zurück, wenn Sie dieselben Argumente übergeben. Wenn Sie die Memoisierung für unreine Funktionen verwenden, verbessern Sie nicht die Leistung, sondern erhöhen Ihren Overhead. Das liegt daran, dass Sie jedes Mal, wenn Sie sich eine Funktion merken, die Geschwindigkeit dem Speicher vorziehen.
Auswendiglernen in React
Wenn Sie React-Komponenten optimieren möchten, bietet React Memoization über den Hook useMemo(), React.memo und useCallBack().
Verwenden von useMemo()
useMemo() ist ein Haken reagieren die eine Funktion und ein Abhängigkeitsarray akzeptiert.
konst memoizedValue = useMemo(() => computeExpensiveValue (a, b), [a, b]);
Es speichert den von dieser Funktion zurückgegebenen Wert. Die Werte im Abhängigkeitsarray bestimmen, wann die Funktion ausgeführt wird. Erst wenn sie sich ändern, wird die Funktion erneut ausgeführt.
Beispielsweise hat die folgende App-Komponente einen gespeicherten Wert namens result.
importieren {useMemo} aus "reagieren"
FunktionApp(Wert) {
konst Quadrat = (Wert) => {
Rückkehr Wert * Wert
}
konst result = useMemo(
() => Quadrat (Wert),
[ Wert ]
);
Rückkehr (
<div>{Ergebnis (5)}</div>
)
}
Die App-Komponente ruft bei jedem Rendern square() auf. Die Leistung verschlechtert sich, wenn die App-Komponente aufgrund von häufig gerendert wird Requisiten reagieren Ändern oder Aktualisieren des Status, insbesondere wenn die Funktion square() teuer ist.
Da useMemo() jedoch die zurückgegebenen Werte zwischenspeichert, wird die quadratische Funktion nicht bei jeder erneuten Wiedergabe ausgeführt, es sei denn, die Argumente im Abhängigkeitsarray ändern sich.
Verwendung von React.memo()
React.memo() ist eine Komponente höherer Ordnung, die eine React-Komponente und eine Funktion als Argumente akzeptiert. Die Funktion bestimmt, wann die Komponente aktualisiert werden soll.
Die Funktion ist optional, und wenn sie nicht bereitgestellt wird, führt React.memo einen flachen Kopiervergleich der aktuellen Props der Komponente mit ihren vorherigen Props durch. Wenn die Requisiten unterschiedlich sind, wird ein Update ausgelöst. Wenn die Requisiten gleich sind, wird das erneute Rendern übersprungen und die gespeicherten Werte wiederverwendet.
Die optionale Funktion akzeptiert die vorherigen Requisiten und die nächsten Requisiten als Argumente. Sie können diese Requisiten dann explizit vergleichen, um zu entscheiden, ob die Komponente aktualisiert werden soll oder nicht.
Reagieren.Memo(Komponente, [sindgleich (prevProps, nextProps)])
Schauen wir uns zunächst ein Beispiel ohne das optionale Funktionsargument an. Unten ist eine Komponente namens Kommentare, die den Namen und die E-Mail-Requisiten akzeptiert.
FunktionKommentare ({Name, Kommentar, Likes}) {
Rückkehr (
<div>
<p>{Name}</p>
<p>{Kommentar}</p>
<p>{Likes}</p>
</div>
)
}
Die Komponente für auswendig gelernte Kommentare wird wie folgt von React.memo umschlossen:
konst MemoizedComment = React.memo (Kommentar)
Sie können es wie jede andere React-Komponente aufrufen und dann aufrufen.
<MemoizedComment name="Maria" Kommentar="Memorieren ist großartig" mag=1/>
Wenn Sie den Props-Vergleich selbst durchführen möchten, übergeben Sie die folgende Funktion als zweites Argument an React.memo.
importieren Reagieren aus "reagieren"
FunktioncheckCommentProps(vorherigeRequisiten, nächsteRequisiten) {
Rückkehr prevProps.name nächsteProps.name
&& prevProps.Kommentar nextProps.Kommentar
&& prevProps.likes nextProps.likes
}
konst MemoizedComment = React.memo (Kommentare, checkCommentProps)
Wenn checkProfileProps true zurückgibt, wird die Komponente nicht aktualisiert. Andernfalls wird es erneut gerendert.
Die benutzerdefinierte Funktion ist nützlich, wenn Sie das erneute Rendern anpassen möchten. Beispielsweise könnten Sie es verwenden, um die Komponente „Kommentare“ nur dann zu aktualisieren, wenn sich die Anzahl der „Gefällt mir“-Angaben ändert.
Im Gegensatz zum Hook useMemo(), der nur den zurückgegebenen Wert einer Funktion speichert, speichert React.memo die gesamte Funktion.
Verwenden Sie React.memo nur für reine Komponenten. Um die Vergleichskosten zu senken, merken Sie sich außerdem nur Komponenten, deren Requisiten sich häufig ändern.
Verwenden von useCallBack()
Sie können den useCallBack()-Hook zum Merken verwenden Funktionskomponenten.
konst memoizedCallback = useCallback(
() => {
etwas tun (a, b);
},
[ein, b],
);
Die Funktion wird nur aktualisiert, wenn sich die Werte im Abhängigkeitsarray ändern. Der Hook funktioniert wie der useMemo()-Callback, aber er speichert die Funktionskomponente zwischen den Rendervorgängen, anstatt sich Werte zu merken.
Betrachten Sie das folgende Beispiel einer auswendig gelernten Funktion, die eine API aufruft.
importieren { useCallback, useEffect } aus "reagieren";
konst Komponente = () => {
konst getData = useCallback(() => {
Konsole.log ('eine API aufrufen');
}, []);
useEffect(() => {
Daten bekommen();
}, [Daten bekommen]);
};
Die in useEffect aufgerufene getData()-Funktion wird nur erneut aufgerufen, wenn sich der getData-Wert ändert.
Sollten Sie auswendig lernen?
In diesem Tutorial haben Sie gelernt, was Memoisierung ist, welche Vorteile sie hat und wie Sie sie in JavaScript und React implementieren. Sie sollten jedoch wissen, dass React bereits schnell ist. In den meisten Fällen erhöht das Merken von Komponenten oder Werten die Vergleichskosten und verbessert nicht die Leistung. Merken Sie sich deshalb nur teure Komponenten.
React 18 führte auch neue Hooks wie useId, useTransition und useInsertionEffect ein. Sie können diese verwenden, um die Leistung und Benutzererfahrung von React-Anwendungen zu verbessern.