Memoizacija je tehnika optimizacije, podobna predpomnjenju. Deluje tako, da shrani prejšnje rezultate klica funkcije in te rezultate uporabi ob naslednjem zagonu funkcije. Še posebej je uporabno v aplikacijah, ki zahtevajo veliko računanja in ponavljajo klice funkcij za iste parametre.
Memoizacijo lahko uporabljate v navadnem JavaScriptu in tudi v Reactu na nekaj različnih načinov.
Memoizacija v JavaScriptu
Če želite zapomniti funkcijo v JavaScriptu, morate rezultate te funkcije shraniti v predpomnilnik. Predpomnilnik je lahko objekt z argumenti kot ključi in rezultati kot vrednostmi.
Ko pokličete to funkcijo, najprej preveri, ali je rezultat prisoten v predpomnilniku, preden se zažene. Če je, vrne predpomnjene rezultate. V nasprotnem primeru se izvrši.
Razmislite o tej funkciji:
funkcijokvadrat(št) {
vrnitev št * št
}
Funkcija sprejme argument in vrne njegov kvadrat.
Če želite zagnati funkcijo, jo pokličite s številko, kot je ta:
kvadrat (5) // 25
S 5 kot argumentom bo square() deloval precej hitro. Če pa bi računali na kvadrat 70.000, bi prišlo do opazne zamude. Ne veliko, a vseeno z zamudo. Če bi funkcijo poklicali večkrat in opravili 70.000, bi pri vsakem klicu prišlo do zamude.
To zamudo lahko odpravite z memoizacijo.
konst memoizedSquare = () => {
pustiti predpomnilnik = {};
vrnitev (število) => {
če (št. v predpomnilnik) {
console.log('Ponovna uporaba predpomnjene vrednosti');
vrnitev predpomnilnik[št];
} drugače {
console.log('Rezultat izračuna');
pustiti rezultat = num * num;
// predpomnilnik the novorezultatvrednostzaNaslednjičas
predpomnilnik[št] = rezultat;
vrnitev rezultat;
}
}
}
V tem primeru funkcija preveri, ali je rezultat že izračunala, tako da preveri, ali obstaja v objektu predpomnilnika. Če ima, vrne že izračunano vrednost.
Ko funkcija prejme novo številko, izračuna novo vrednost in rezultate shrani v predpomnilnik, preden se vrne.
Tudi ta primer je precej preprost, vendar pojasnjuje, kako bi memoizacija delovala za izboljšanje učinkovitosti programa.
Zapomnite si samo čiste funkcije. Te funkcije vrnejo enak rezultat, ko posredujete enake argumente. Če memoizacijo uporabljate pri nečistih funkcijah, ne boste izboljšali zmogljivosti, ampak povečali stroške. To je zato, ker izberete hitrost namesto pomnilnika vsakič, ko si zapomnite funkcijo.
Memoizacija v Reactu
Če želite optimizirati komponente React, React zagotavlja memoizacijo prek kljuke useMemo(), React.memo in useCallBack().
Uporaba useMemo()
useMemo() je a React hook ki sprejme funkcijo in matriko odvisnosti.
konst memoizedValue = useMemo(() => computeExpensiveValue (a, b), [a, b]);
Zapomni si vrednost, vrnjeno iz te funkcije. Vrednosti v matriki odvisnosti narekujejo, kdaj se funkcija izvede. Šele ko se spremenijo, se funkcija znova izvede.
Naslednja komponenta aplikacije ima na primer memoizirano vrednost, imenovano rezultat.
uvoz {useMemo} od "reagirati"
funkcijoaplikacija(vrednost) {
konst kvadrat = (vrednost) => {
vrnitev vrednost * vrednost
}
konst rezultat = useMemo(
() => kvadrat (vrednost),
[ vrednost ]
);
vrnitev (
<div>{rezultat (5)}</div>
)
}
Komponenta aplikacije pokliče square() pri vsakem upodabljanju. Zmogljivost se bo zmanjšala, če bo komponenta aplikacije večkrat upodobljena zaradi React props spreminjanje ali posodabljanje stanja, še posebej, če je funkcija square() draga.
Ker pa useMemo() predpomni vrnjene vrednosti, se kvadratna funkcija ne izvede pri vsakem ponovnem upodabljanju, razen če se spremenijo argumenti v nizu odvisnosti.
Uporaba React.memo()
React.memo() je komponenta višjega reda, ki sprejme komponento React in funkcijo kot argumenta. Funkcija določa, kdaj naj se komponenta posodobi.
Funkcija je neobvezna in če ni na voljo, React.memo naredi plitvo primerjavo kopij trenutnih rekvizitov komponente z njenimi prejšnjimi rekviziti. Če so rekviziti drugačni, sproži posodobitev. Če so rekviziti enaki, preskoči ponovno upodobitev in znova uporabi memoizirane vrednosti.
Izbirna funkcija sprejme prejšnje in naslednje rekvizite kot argumente. Nato lahko eksplicitno primerjate te rekvizite, da se odločite, ali posodobiti komponento ali ne.
Reagiraj.memo(Komponenta, [areEqual (prevProps, nextProps)])
Najprej si oglejmo primer brez neobveznega argumenta funkcije. Spodaj je komponenta z imenom Komentarji, ki sprejema rekvizite za ime in e-pošto.
funkcijoKomentarji ({ime, komentar, všečki}) {
vrnitev (
<div>
<str>{name}</str>
<str>{komentar}</str>
<str>{všeč mi je}</str>
</div>
)
}
Komponenta memoiziranih komentarjev bo imela React.memo ovit okoli sebe takole:
konst MemoizedComment = React.memo (Komentar)
Lahko ga pokličete in nato pokličete kot katero koli drugo komponento React.
<MemoizedComment name="Mary" komentar="Memoizacija je odlična" všečki=1/>
Če želite sami izvesti primerjavo rekvizitov, posredujte React.memo naslednjo funkcijo kot drugi argument.
uvoz Reagiraj od "reagirati"
funkcijocheckCommentProps(prevProps, nextProps) {
vrnitev prevProps.name nextProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes
}
konst MemoizedComment = React.memo (Komentarji, checkCommentProps)
Če checkProfileProps vrne true, komponenta ni posodobljena. V nasprotnem primeru se ponovno upodobi.
Funkcija po meri je uporabna, ko želite prilagoditi ponovno upodabljanje. Uporabite ga lahko na primer za posodobitev komponente komentarjev samo, ko se spremeni število všečkov.
Za razliko od kljuke useMemo(), ki si zapomni samo vrnjeno vrednost funkcije, React.memo zapomni celotno funkcijo.
Uporabite React.memo samo za čiste komponente. Poleg tega si za zmanjšanje stroškov primerjave zapomnite le komponente, katerih rekviziti se pogosto spreminjajo.
Uporaba useCallBack()
Za memoize lahko uporabite kavelj useCallBack(). funkcijske komponente.
konst memoizedCallback = useCallback(
() => {
narediti nekaj (a, b);
},
[a, b],
);
Funkcija se posodobi le, ko se spremenijo vrednosti v nizu odvisnosti. Kavelj deluje kot povratni klic useMemo(), vendar zapomni komponento funkcije med upodobitvami namesto zapomnitve vrednosti.
Razmislite o naslednjem primeru memoizirane funkcije, ki kliče API.
uvoz {useCallback, useEffect} od "reagirati";
konst Komponenta = () => {
konst getData = useCallback(() => {
console.log('pokličite API');
}, []);
useEffect(() => {
getData();
}, [getData]);
};
Funkcija getData(), poklicana v useEffect, bo znova poklicana le, ko se spremeni vrednost getData.
Bi morali memoizirati?
V tej vadnici ste izvedeli, kaj je memoizacija, njene prednosti in kako jo implementirati v JavaScript in React. Vedeti pa morate, da je React že hiter. V večini primerov zapomnitev komponent ali vrednosti poveča stroške primerjave in ne izboljša učinkovitosti. Zaradi tega si zapomnite samo drage komponente.
React 18 je predstavil tudi nove kljuke, kot so useId, useTransition in useInsertionEffect. Te lahko uporabite za izboljšanje delovanja in uporabniške izkušnje aplikacij React.