Performance optimerings hook useMemo i React
Den første hook til performance optimering,
som vi vil se på,
er useMemo.
Denne hook hjælper med at cache resultater af ressourcekrævende operationer mellem genrendringer af skærmen og kan dermed hjælpe med at undgå unødvendige omkostningsrige beregninger. Denne form for caching kaldes også memoization.
Lad os se, hvordan det virker. Lad os
oprette en komponent med en knap og
en overskrift h3:
return (
<div>
<h3>Text</h3>
<button>click</button>
</div>
);
Og lad os nu gøre det sådan, at når der klikkes
på overskriften, skifter dens farve fra orange
til grøn og tilbage. Til at starte med
opretter vi en state isGreen:
const [isGreen, setIsGreen] = useState(false);
Lad os tilføje en betingelse for at ændre farven på overskriften i attributten style
og tilføje en klik-håndtering:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Text</h3>
Lad os også have en værdi, som øges med én, når der klikkes på vores knap. Lad os oprette en state for den:
const [num, setNum] = useState(0);
Lad os tilføje håndtering af klik på knappen:
<button onClick={() => setNum(num + 1)}>
clicks
</button>
Lad os også have en funktion
square, som returnerer
kvadratet af værdien num. Resultatet
af funktionskaldet vil vi gemme i
variablen result:
const result = square(num);
function square(num) {
return num * num;
}
Lad os vise result i knappens tekst:
<button onClick={() => setNum(num + 1)}>
clicks: {result}
</button>
Resultatet blev følgende:
når der klikkes på knappen, ændres værdien
num, som derefter bliver
opløftet til anden potens, og når der klikkes på overskriften
ændres overskriftens farve.
Vores komponent er meget lille, alt virker hurtigt, på trods af at når der klikkes på overskriften for at skifte dens farve, bliver hele komponenten gengivet igen, hvilket betyder at beregningerne knyttet til knappen også sker igen, selvom vi ikke rørte ved den. Og forestil dig nu, hvis vores beregninger var omkostningsrige og alt blev genberegnet hver gang.
Lad os gøre vores funktion lidt tungere, nu vil den tænke lidt længere. På denne måde simulerer vi langsomme beregninger:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Bare gør ingenting ...
}
return num * num;
}
Prøv at klikke på overskriften nu. Det viser sig,
at på grund af funktionens square langsomme arbejde
(og vi rører ikke knappen)
skal vi vente en evighed for at
overskriftens farve skal skifte!
Her kommer useMemo hook til vores
undsætning. For at gøre dette skal vi som den første
parameter sende en funktion, der beregner
værdien, som vi ønsker at cache,
denne funktion skal være ren og ikke
tage nogen parametre. Og som den anden
parameter - afhængigheder i firkantede
parenteser, med andre ord, alle de reaktive
værdier, der deltager i funktionens kode.
På denne måde vil vi i result
skrive en sådan konstruktion:
const result = useMemo(() => square(num), [num]);
Lad os klikke på overskriften igen. Nu,
hvis vi ikke rører knappen med beregningerne
og dermed ikke ændrer værdien af state
num, bliver intet genberegnet,
og React viser den cachelagrede værdi
i knappen, derfor skifter vores overskrift
hurtigt farve.
Opret en komponent App, placer
et afsnit i den. Opret en state text
med startværdien 'react',
lad state-værdien vises
som afsnittets tekst. Lad det sådan, at når der klikkes
på afsnittet, tilføjes et
udråbstegn til slutningen af teksten.
Opret endnu en state num, med
startværdi 0. Placer i
App endnu et afsnit. Gør det sådan,
at når der klikkes på det, øges num
med 1.
Og tilføj nu i App funktionen
triple, som som
parameter tager num og
returnerer dens tredobbelte værdi.
Læg resultatet af funktionskaldet
i variablen result. Vis
result som teksten i det andet afsnit.
Klik efter hinanden på afsnittene,
og læg mærke til, hvor langsomt
udråbstegnene tilføjes.
Ret situationen ved at pakke den langsomme
funktion triple ind i useMemo.