Uporaba optimizacijskega kavčka useMemo za zmogljivost v Reactu
Prvi kavček za optimizacijo
zmogljivosti, ki ga bomo obravnavali,
je useMemo.
Ta kavček pomaga predpomniti rezultate zahtevnih operacij med trenutki ponovnega izrisa zaslona in lahko ustrezno pomaga preprečiti nepotrebne obsežne izračune. Takšno predpomnjenje imenujemo tudi memoizacija.
Poglejmo, kako to deluje. Ustvarimo
komponento z gumbom in
naslovom h3:
return (
<div>
<h3>Text</h3>
<button>click</button>
</div>
);
Zdaj pa naredimo tako, da se ob kliku
na naslov njegova barva spremeni iz oranžne
v zeleno in obratno. Za začetek
ustvarimo stanje isGreen:
const [isGreen, setIsGreen] = useState(false);
Dodajmo v atribut style naslova
pogoj spreminjanja barve naslovu in
dodajmo obravnavalnik klika:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Text</h3>
Naj imamo tudi kakšno vrednost, ki se bo povečala ob kliku na naš gumb za ena. Ustvarimo zanjo stanje:
const [num, setNum] = useState(0);
Dodajmo obravnavo klika na gumb:
<button onClick={() => setNum(num + 1)}>
clicks
</button>
Naj imamo tudi neko funkcijo
square, ki bo vrnila
kvadrat vrednosti num. Rezultat
klica funkcije bomo zapisali v
spremenljivko result:
const result = square(num);
function square(num) {
return num * num;
}
Prikažimo result v besedilu gumba:
<button onClick={() => setNum(num + 1)}>
clicks: {result}
</button>
Kot rezultat smo dobili naslednje:
ob kliku na gumb se spremeni vrednost
num, ki se nato kvadrira,
ob kliku na naslov
pa se spremeni barva naslova.
Imamo zelo majhno komponento, vse deluje hitro, kljub temu, da se ob kliku na naslov za spremembo njegove barve celotna komponenta ponovno izriše, zato se ponovno zgodijo tudi izračuni, ki so povezani z gumbom, in to celo takrat, ko se ga nismo dotaknili. In zdaj pa si predstavljajte, če bi bili naši izračuni obsežni in bi se vse ponovno preračunalo vsakič.
Malo otežimo našo funkcijo, zdaj bo malo dlje razmišljala. S tem bomo simulirali dolge izračune:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Samo ne naredi nič ...
}
return num * num;
}
Zdaj klikajte na naslov. Izkazalo se je,
da zdaj zaradi dolgega delovanja funkcije
square (gumba pa se ne dotikamo)
moramo čakati celo večnost, da se
naslovu spremeni barva!
Tukaj nam bo na pomoč priskočil kavček
useMemo. Za to moramo kot prvi
parameter posredovati funkcijo, ki izračuna
vrednost, ki jo želimo predpomniti,
ta funkcija mora biti čista in ne
sprejemati nobenih parametrov. Kot drugi
parameter pa - odvisnosti v oglatih
oklepajih, z drugimi besedami, vse reaktivne
vrednosti, ki sodelujejo v kodi
funkcije. Tako bomo zdaj v result
zapisali takšno konstrukcijo:
const result = useMemo(() => square(num), [num]);
Ponovno klikajmo na naslov. Zdaj,
če se ne dotaknemo gumba z izračuni
in s tem ne spremenimo vrednosti stanja
num, se nič ne preračuna,
in React prikaže predpomjnjeno vrednost
v gumbu, zato naš naslov
hitro spremeni svojo barvo.
Ustvarite komponento App, postavite
vanjo odstavek. Ustvarite stanje text
z začetno vrednostjo 'react',
naj se vrednost stanja prikaže
kot besedilo odstavka. Naj ob kliku
na odstavek, se mu na konec besedila doda
klicaj.
Ustvarite še eno stanje num, z
začetno vrednostjo 0. Postavite v
App še en odstavek. Naredite tako,
da se ob kliku nanj num
poveča za 1.
In zdaj dodajte v App funkcijo
triple, ki kot
parameter sprejme num in
vrne njegovo potrojeno vrednost.
Rezultat klica funkcije
shranite v spremenljivko result. Prikažite
result kot besedilo drugega
odstavka. Klikajte po vrsti na odstavke,
opazite, kako počasi se dodajajo
klicaji.
Popravite situacijo, tako da počasno
funkcijo triple ovijete z useMemo.