Memoizacija je tehnika optimizacije, slična predmemoriranju. Radi tako da pohranjuje prethodne rezultate poziva funkcije i koristi te rezultate sljedeći put kada se funkcija pokrene. Osobito je koristan u računalno zahtjevnim aplikacijama koje ponavljaju pozive funkcija na istim parametrima.

Memoizaciju možete koristiti u običnom JavaScriptu i također u Reactu, na nekoliko različitih načina.

Memoizacija u JavaScriptu

Da biste zapamtili funkciju u JavaScriptu, trebate pohraniti rezultate te funkcije u predmemoriju. Predmemorija može biti objekt s argumentima kao ključevima i rezultatima kao vrijednostima.

Kada pozovete ovu funkciju, ona prvo provjerava je li rezultat prisutan u predmemorij prije pokretanja. Ako jest, vraća predmemorirane rezultate. Inače se izvršava.

Razmotrite ovu funkciju:

funkcijakvadrat(br) {
povratak br * br
}

Funkcija prima argument i vraća njegov kvadrat.

Da biste pokrenuli funkciju, pozovite je s ovakvim brojem:

kvadrat(5) // 25

Uz 5 kao argument, square() će raditi prilično brzo. Međutim, ako biste izračunali kvadrat od 70 000, došlo bi do primjetnog kašnjenja. Ne puno, ali ipak kasni. Sada, ako biste pozvali funkciju više puta i prošli 70.000, doživjeli biste kašnjenje u svakom pozivu.

instagram viewer

Ovo kašnjenje možete eliminirati korištenjem memoizacije.

konst memoizedSquare = () => {
neka predmemorija = {};
povratak (broj) => {
ako (broj in predmemorija) {
console.log('Ponovno korištenje predmemorirane vrijednosti');
povratak predmemorija[br];
} drugo {
console.log('Rezultat izračuna');
neka rezultat = num * num;

// predmemorija the noviproizlazitivrijednostzaSljedećivrijeme
predmemorija[br] = proizlaziti;
povratak proizlaziti;
}
}
}

U ovom primjeru funkcija provjerava je li prethodno izračunala rezultat provjerom postoji li u objektu predmemorije. Ako ima, vraća već izračunatu vrijednost.

Kada funkcija primi novi broj, izračunava novu vrijednost i pohranjuje rezultate u predmemoriju prije nego što se vrati.

Opet ovaj primjer je prilično jednostavan, ali objašnjava kako bi memoizacija radila na poboljšanju performansi programa.

Trebali biste zapamtiti samo čiste funkcije. Ove funkcije vraćaju isti rezultat kada proslijedite iste argumente. Ako koristite memoizaciju na nečistim funkcijama, nećete poboljšati performanse, već ćete povećati troškove. To je zato što birate brzinu umjesto memorije svaki put kada memorirate funkciju.

Memoizacija u Reactu

Ako želite optimizirati komponente Reacta, React pruža memoizaciju putem useMemo() kuke, React.memo i useCallBack().

Korištenje useMemo()

useMemo() je a Reagirajte kuku koji prihvaća funkciju i niz ovisnosti.

konst memoizedValue = useMemo(() => computeExpensiveValue (a, b), [a, b]);

Memorira vrijednost vraćenu iz te funkcije. Vrijednosti u nizu ovisnosti određuju kada se funkcija izvršava. Tek kada se promijene funkcija se ponovno izvršava.

Na primjer, sljedeća komponenta aplikacije ima memoiziranu vrijednost koja se zove rezultat.

uvoz {useMemo} iz "reagirati"
funkcijaaplikacija(vrijednost) {
konst kvadrat = (vrijednost) => {
povratak vrijednost * vrijednost
}
konst rezultat = useMemo(
() => kvadrat (vrijednost),
[ vrijednost ]
);
povratak (
<div>{rezultat (5)}</div>
)
}

Komponenta aplikacije poziva square() pri svakom prikazu. Izvedba će se smanjiti ako se komponenta aplikacije renderira mnogo puta zbog React rekviziti mijenjanje ili ažuriranje stanja, posebno ako je funkcija square() skupa.

Međutim, budući da useMemo() sprema vraćene vrijednosti, kvadratna funkcija se ne izvršava pri svakom ponovnom prikazivanju osim ako se argumenti u nizu ovisnosti ne promijene.

Korištenje React.memo()

React.memo() je komponenta višeg reda koja prihvaća React komponentu i funkciju kao argumente. Funkcija određuje kada komponentu treba ažurirati.

Funkcija je opcijska i ako nije dostupna, React.memo uspoređuje plitku kopiju trenutnih rekvizita komponente s prethodnim rekvizitima. Ako su rekviziti drugačiji, pokreće se ažuriranje. Ako su rekviziti isti, preskače ponovno iscrtavanje i ponovno koristi memoizirane vrijednosti.

Opcijska funkcija prihvaća prethodne i sljedeće rekvizite kao argumente. Zatim možete eksplicitno usporediti ove rekvizite kako biste odlučili hoćete li ažurirati komponentu ili ne.

Reagirati.dopis(komponenta, [su jednaki (prevProps, nextProps)])

Pogledajmo najprije primjer bez opcijskog argumenta funkcije. Ispod je komponenta pod nazivom Komentari koja prihvaća propise za ime i e-poštu.

funkcijaKomentari ({ime, komentar, lajkovi}) {
povratak (
<div>
<str>{Ime}</str>
<str>{komentar}</str>
<str>{sviđa mi se}</str>
</div>
)
}

Komponenta memoiziranih komentara imat će React.memo omotan oko sebe ovako:

konst MemoizedComment = React.memo (Komentar)

Možete je pozvati i zatim pozvati kao bilo koju drugu React komponentu.

<MemoizedComment name="Marija" komentar="Memoizacija je odlična" lajkovi=1/>

Ako želite sami izvršiti usporedbu rekvizita, proslijedite sljedeću funkciju u React.memo kao drugi argument.

uvoz Reagirati iz "reagirati"
funkcijacheckCommentProps(prevProps, nextProps) {
povratak prevProps.name nextProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes
}

konst MemoizedComment = React.memo (Komentari, checkCommentProps)

Ako checkProfileProps vrati true, komponenta nije ažurirana. U suprotnom se ponovno prikazuje.

Prilagođena funkcija korisna je kada želite prilagoditi ponovno iscrtavanje. Na primjer, možete ga koristiti za ažuriranje komponente Komentari samo kada se promijeni broj sviđanja.

Za razliku od useMemo() kuke koja pamti samo vraćenu vrijednost funkcije, React.memo memoizira cijelu funkciju.

Koristite React.memo samo za čiste komponente. Također, kako biste smanjili troškove usporedbe, memoirajte samo komponente čiji se rekviziti često mijenjaju.

Upotreba useCallBack()

Možete koristiti useCallBack() kuku za memoriranje komponente funkcije.

konst memoizedCallback = useCallback(
() => {
učiniti nešto (a, b);
},
[a, b],
);

Funkcija se ažurira samo kada se promijene vrijednosti u nizu ovisnosti. Priključak radi kao povratni poziv useMemo(), ali memoizira komponentu funkcije između renderiranja umjesto memoiziranja vrijednosti.

Razmotrite sljedeći primjer memoizirane funkcije koja poziva API.

uvoz {useCallback, useEffect} iz "reagirati";
konst Komponenta = () => {
konst getData = useCallback(() => {
console.log('nazovite API');
}, []);
useEffect(() => {
getData();
}, [getData]);
};

Funkcija getData() pozvana u useEffect bit će ponovno pozvana samo kada se promijeni vrijednost getData.

Trebate li memoizirati?

U ovom ste vodiču naučili što je memoizacija, njene prednosti i kako je implementirati u JavaScript i React. Međutim, trebali biste znati da je React već brz. U većini slučajeva memoriranje komponenti ili vrijednosti povećava troškove usporedbe, a ne poboljšava izvedbu. Zbog toga memoirajte samo skupe komponente.

React 18 također je uveo nove kuke kao što su useId, useTransition i useInsertionEffect. Možete ih koristiti za poboljšanje performansi i korisničkog iskustva React aplikacija.