Optimalizačný hook pre zvýšenie výkonu useMemo v Reacte
Prvý hook na optimalizáciu
výkonu, ktorý si predstavíme,
je useMemo.
Tento hook pomáha ukladať do vyrovnávacej pamäte výsledky náročných operácií medzi prekresleniami obrazovky a tým môže pomôcť vyhnúť sa zbytočným objemným výpočtom. Takéto ukladanie do vyrovnávacej pamäte sa nazýva aj memorizácia.
Pozrime sa, ako to funguje. Vytvorme
komponent s tlačidlom a
nadpisom h3:
return (
<div>
<h3>Text</h3>
<button>click</button>
</div>
);
A teraz urobme tak, aby sa pri kliknutí
na nadpis zmenila jeho farba z oranžovej
na zelenú a späť. Na začiatok
vytvorme stav isGreen:
const [isGreen, setIsGreen] = useState(false);
Pridajme do atribútu style nadpisu
podmienku zmeny farby nadpisu a
nastavme obsluhu kliknutia:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Text</h3>
Nech máme tiež nejakú hodnotu, ktorá sa bude zvyšovať pri kliknutí na naše tlačidlo o jednu. Vytvorme pre ňu stav:
const [num, setNum] = useState(0);
Pridajme obsluhu kliknutia na tlačidlo:
<button onClick={() => setNum(num + 1)}>
clicks
</button>
Nech máme tiež nejakú funkciu
square, ktorá bude vracať
štvorec hodnoty num. Výsledok
volania funkcie zapíšeme do
premennej result:
const result = square(num);
function square(num) {
return num * num;
}
Vypíšme result v texte tlačidla:
<button onClick={() => setNum(num + 1)}>
clicks: {result}
</button>
Výsledkom bolo nasledovné:
pri kliknutí na tlačidlo sa zmení hodnota
num, ktorá sa potom umocní
na druhú, a pri kliknutí na nadpis
sa zmení farba nadpisu.
Máme veľmi malý komponent, všetko funguje rýchlo, napriek tomu, že pri kliknutí na nadpis na zmenu jeho farby sa celý komponent prekreslí znova, preto sa znova vykonajú aj výpočty, ktoré sú priradené k tlačidlu, a to aj pri tom, že sme sa ho nedotkli. A teraz si predstavte, keby naše výpočty boli objemné a všetko sa prepočítavalo znova každý raz.
Poďme, trochu zaťažme našu funkciu, teraz bude "premýšľať" trochu dlhšie. Týmto spôsobom simulujeme dlhé výpočty:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Proste nerob nič ...
}
return num * num;
}
Klikajte teraz na nadpis. Vychádza to tak,
že teraz kvôli dlhej činnosti funkcie
square (a tlačidlo sme sa nedotkli)
musíme čakať celú večnosť, aby sa
nadpisu zmenila farba!
Tu nám príde na pomoc hook
useMemo. Na to potrebujeme ako prvým
parametrom odovzdať funkciu, ktorá vypočíta
hodnotu, ktorú chceme uložiť do vyrovnávacej pamäte,
táto funkcia musí byť čistá a
neprijímať žiadne parametre. A druhým
parametrom - závislosti v hranatých
zátvorkách, inými slovami, všetky reaktívne
hodnoty, ktoré sú použité v kóde
funkcie. Týmto spôsobom, do result
teraz napíšeme takúto konštrukciu:
const result = useMemo(() => square(num), [num]);
Klikajme znova na nadpis. Teraz,
ak sa nedotkneme tlačidla s výpočtami
a takým spôsobom nemeníme hodnotu stavu
num, tak sa nič neprepočítava,
a React zobrazuje hodnotu uloženú v vyrovnávacej pamäti
v tlačidle, preto náš nadpis
rýchlo mení svoju farbu.
Vytvorte komponent App, umiestnite
v ňom odsek. Vytvorte stav text
s počiatočnou hodnotou 'react',
nech sa hodnota stavu zobrazuje
ako text odseku. Nech pri kliknutí
na odsek sa mu na koniec textu pridá
výkričník.
Vytvorte ešte jeden stav num, s
počiatočnou hodnotou 0. Umiestnite v
App ešte jeden odsek. Urobte tak,
aby pri kliknutí naň sa num
zväčšila o 1.
A teraz pridajte do App funkciu
triple, ktorá ako
parameter prijme num a
vráti jeho strojnásobnú hodnotu.
Vložte výsledok volania funkcie
do premennej result. Zobrazte
result ako text druhého
odseku. Klikajte postupne na odseky,
všimnite si, ako pomaly sa pridávajú
výkričníky.
Opravte situáciu, obalením pomalej
funkcie triple do useMemo.