Zapamätanie je optimalizačná technika podobná ukladania do vyrovnávacej pamäte. Funguje tak, že sa uložia predchádzajúce výsledky volania funkcie a tieto výsledky sa použijú pri ďalšom spustení funkcie. Je to užitočné najmä vo výpočtovo náročných aplikáciách, ktoré opakujú volania funkcií s rovnakými parametrami.
Memoizáciu môžete použiť v jednoduchom JavaScripte a tiež v Reacte niekoľkými rôznymi spôsobmi.
Zapamätanie v JavaScripte
Ak si chcete zapamätať funkciu v JavaScripte, musíte uložiť výsledky tejto funkcie do vyrovnávacej pamäte. Cache môže byť objekt s argumentmi ako kľúčmi a výsledkami ako hodnotami.
Keď túto funkciu zavoláte, pred spustením najskôr skontroluje, či sa výsledok nachádza vo vyrovnávacej pamäti. Ak áno, vráti výsledky uložené vo vyrovnávacej pamäti. V opačnom prípade sa vykoná.
Zvážte túto funkciu:
funkciunámestie(č) {
vrátiť num * num
}
Funkcia prevezme argument a vráti svoju druhú mocninu.
Ak chcete spustiť funkciu, zavolajte ju číslom, ako je toto:
námestie(5) // 25
S argumentom 5 bude square() bežať veľmi rýchlo. Ak by ste však vypočítali druhú mocninu 70 000, došlo by k citeľnému oneskoreniu. Nie o veľa, ale s oneskorením. Ak by ste teraz zavolali funkciu viackrát a minuli 70 000, zažili by ste oneskorenie pri každom volaní.
Toto oneskorenie môžete odstrániť pomocou memorovania.
konšt memoizedSquare = () => {
nech cache = {};
vrátiť (num) => {
if (počet in cache) {
console.log('Opätovné použitie hodnoty vo vyrovnávacej pamäti');
vrátiť cache[č];
} inak {
console.log('Vypočítava sa výsledok');
nech vysledok = num * num;
// cache na NovývýsledokhodnotupreĎalšiečas
cache[č] = výsledok;
vrátiť výsledok;
}
}
}
V tomto príklade funkcia skontroluje, či bol výsledok vypočítaný skôr, a to tak, že skontroluje, či existuje v objekte vyrovnávacej pamäte. Ak má, vráti už vypočítanú hodnotu.
Keď funkcia dostane nové číslo, vypočíta novú hodnotu a uloží výsledky do vyrovnávacej pamäte predtým, ako sa vráti.
Tento príklad je opäť celkom jednoduchý, ale vysvetľuje, ako by memorovanie fungovalo na zlepšenie výkonu programu.
Mali by ste si zapamätať iba čisté funkcie. Tieto funkcie vrátia rovnaký výsledok, keď zadáte rovnaké argumenty. Ak použijete memorovanie na nečisté funkcie, nezlepšíte výkon, ale zvýšite svoju réžiu. Je to preto, že pri každom uložení funkcie do pamäte uprednostňujete rýchlosť pred pamäťou.
Zapamätanie v React
Ak hľadáte optimalizáciu komponentov Reactu, React poskytuje zapamätanie pomocou háku useMemo(), React.memo a useCallBack().
Použitie funkcie useMemo()
useMemo() je a Reagovať hák ktorý akceptuje funkciu a pole závislostí.
konšt memoizedValue = useMemo(() => computeExpensiveValue (a, b), [a, b]);
Zapamätá si hodnotu vrátenú z tejto funkcie. Hodnoty v poli závislostí určujú, kedy sa funkcia vykoná. Až keď sa zmenia, funkcia sa vykoná znova.
Napríklad nasledujúci komponent aplikácie má uloženú hodnotu nazývanú výsledok.
importovať { useMemo } od "reagovať"
funkciuApp(hodnotu) {
konšt štvorec = (hodnota) => {
vrátiť hodnota * hodnota
}
konšt výsledok = useMemo(
() => štvorec (hodnota),
[ hodnota ]
);
vrátiť (
<div>{výsledok (5)}</div>
)
}
Komponent App volá square() pri každom vykreslení. Výkon sa zníži, ak sa komponent aplikácie vykreslí mnohokrát Reagovať rekvizity zmena alebo aktualizácia stavu, najmä ak je funkcia square() drahá.
Keďže však useMemo() ukladá vrátené hodnoty do vyrovnávacej pamäte, funkcia square sa nevykoná pri každom opätovnom vykreslení, pokiaľ sa nezmenia argumenty v poli závislostí.
Pomocou React.memo()
React.memo() je komponent vyššieho rádu, ktorý akceptuje komponent React a funkciu ako argumenty. Funkcia určuje, kedy sa má komponent aktualizovať.
Táto funkcia je voliteľná a ak nie je k dispozícii, React.memo vytvorí plytké porovnanie aktuálnych rekvizít komponentu s predchádzajúcimi rekvizitami. Ak sú rekvizity odlišné, spustí sa aktualizácia. Ak sú rekvizity rovnaké, preskočí opätovné vykreslenie a znova použije uložené hodnoty.
Voliteľná funkcia akceptuje predchádzajúce a nasledujúce podpery ako argumenty. Potom môžete tieto rekvizity explicitne porovnať a rozhodnúť sa, či komponent aktualizovať alebo nie.
Reagovať.memo(Komponent, [areEqual (prevProps, nextProps)])
Pozrime sa najprv na príklad bez argumentu voliteľnej funkcie. Nižšie je uvedený komponent s názvom Komentáre, ktorý akceptuje meno a e-mailové rekvizity.
funkciuKomentáre ({meno, komentár, páči sa mi}) {
vrátiť (
<div>
<p>{názov}</str>
<p>{komentár}</str>
<p>{páči sa mi}</str>
</div>
)
}
Komponent komentárov v pamäti bude mať okolo seba React.memo takto:
konšt MemoizedComment = React.memo (Komentár)
Môžete ho zavolať a potom zavolať ako ktorýkoľvek iný komponent Reactu.
<MemoizedComment name="Mary" komentár ="Zapamätanie je skvelé" páči sa mi=1/>
Ak chcete vykonať porovnanie rekvizít sami, odovzdajte nasledujúcu funkciu React.memo ako druhý argument.
importovať Reagovať od "reagovať"
funkciucheckCommentProps(prevProps, nextProps) {
vrátiť prevProps.name nextProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes
}
konšt MemoizedComment = React.memo (Komentáre, checkCommentProps)
Ak checkProfileProps vráti hodnotu true, komponent sa neaktualizuje. V opačnom prípade sa znova vykreslí.
Vlastná funkcia je užitočná, keď chcete prispôsobiť opätovné vykreslenie. Môžete ho napríklad použiť na aktualizáciu komponentu Komentáre iba vtedy, keď sa zmení počet hodnotení Páči sa mi.
Na rozdiel od háku useMemo(), ktorý si zapamätá iba vrátenú hodnotu funkcie, React.memo si zapamätá celú funkciu.
React.memo používajte len pre čisté komponenty. Ak chcete znížiť náklady na porovnávanie, zapamätajte si iba komponenty, ktorých rekvizity sa často menia.
Použitie useCallBack()
Na zapamätanie môžete použiť háčik useCallBack(). funkčné komponenty.
konšt memoizedCallback = useCallback(
() => {
urobiť niečo (a, b);
},
[a, b],
);
Funkcia sa aktualizuje iba vtedy, keď sa zmenia hodnoty v poli závislostí. Hák funguje ako spätné volanie useMemo(), ale zapamätáva si komponent funkcie medzi rendermi namiesto memorovania hodnôt.
Uvažujme o nasledujúcom príklade funkcie uloženej v pamäti, ktorá volá API.
importovať { useCallback, useEffect } od "reagovať";
konšt Komponent = () => {
konšt getData = useCallback(() => {
console.log('zavolajte API');
}, []);
useEffect(() => {
getData();
}, [getData]);
};
Funkcia getData() volaná v useEffect sa znova zavolá len vtedy, keď sa zmení hodnota getData.
Mali by ste sa naučiť naspamäť?
V tomto návode ste sa naučili, čo je memoizácia, jej výhody a ako ju implementovať do JavaScriptu a Reactu. Mali by ste však vedieť, že React je už rýchly. Vo väčšine prípadov zapamätanie komponentov alebo hodnôt zvyšuje náklady na porovnanie a nezlepšuje výkon. Z tohto dôvodu si zapamätajte iba drahé komponenty.
React 18 tiež predstavil nové háčiky ako useId, useTransition a useInsertionEffect. Môžete ich použiť na zlepšenie výkonu a používateľského zážitku z aplikácií React.