Memoiseerimine on optimeerimistehnika, mis sarnaneb vahemällu salvestamisele. See toimib, salvestades funktsioonikutse eelmised tulemused ja kasutades neid tulemusi järgmisel funktsiooni käivitamisel. See on eriti kasulik arvutusmahukates rakendustes, mis kordavad funktsioonikutseid samadel parameetritel.

Memoiseerimist saate kasutada tavalises JavaScriptis ja ka Reactis mitmel erineval viisil.

Memosioon JavaScriptis

Funktsiooni meeldejätmiseks JavaScriptis peate salvestama selle funktsiooni tulemused vahemällu. Vahemälu võib olla objekt, mille argumendid on võtmed ja tulemused väärtusteks.

Selle funktsiooni kutsumisel kontrollib see enne käivitamist esmalt, kas tulemus on vahemälus olemas. Kui on, tagastab see vahemällu salvestatud tulemused. Vastasel juhul see täidetakse.

Mõelge sellele funktsioonile:

funktsiooniruut(nr) {
tagasi num * num
}

Funktsioon võtab argumendi ja tagastab selle ruudu.

Funktsiooni käivitamiseks helistage sellele sellise numbriga:

ruut(5) // 25

Kui argumendiks on 5, töötab square() üsna kiiresti. Kui aga arvutada ruutu 70 000, oleks märgatav viivitus. Mitte palju, kuid siiski viivitusega. Nüüd, kui kutsuksite funktsiooni mitu korda ja ületaksite 70 000, kogeksite iga kõne viivitust.

instagram viewer

Selle viivituse saate memoiseerimise abil kõrvaldada.

konst memoizedSquare = () => {
lase vahemälu = {};
tagasi (arv) => {
if (nm in vahemälu) {
console.log('Vahemällu salvestatud väärtuse taaskasutamine');
tagasi vahemälu[nr];
} muidu {
console.log('Tulemuse arvutamine');
lase tulemus = arv * arv;

// vahemälu a uustulemusväärtusjaoksjärgmiseksaega
vahemälu[nr] = tulemus;
tagasi tulemus;
}
}
}

Selles näites kontrollib funktsioon, kas tulemus on varem välja arvutatud, kontrollides, kas see on vahemäluobjektis olemas. Kui see on olemas, tagastab see juba arvutatud väärtuse.

Kui funktsioon saab uue numbri, arvutab see uue väärtuse ja salvestab tulemused enne tagastamist vahemällu.

See näide on jällegi üsna lihtne, kuid see selgitab, kuidas memoiseerimine toimiks programmi jõudluse parandamiseks.

Peaksite meelde jätma ainult puhtaid funktsioone. Need funktsioonid tagastavad sama tulemuse, kui sisestate samad argumendid. Kui kasutate ebapuhaste funktsioonide puhul meeldejätmist, ei paranda te jõudlust, vaid suurendate oma üldkulusid. Seda seetõttu, et iga funktsiooni meeldejätmisel valite kiiruse, mitte mälu.

Reactis meeldejätmine

Kui soovite optimeerida Reacti komponente, pakub React meeldejätmist konksu useMemo(), React.memo ja useCallBack().

UseMemo() kasutamine

useMemo() on a Reageerimiskonks mis aktsepteerib funktsiooni ja sõltuvuste massiivi.

konst memoizedValue = useMemo(() => arvutaKallisVäärtus (a, b), [a, b]);

See jätab meelde sellest funktsioonist tagastatud väärtuse. Sõltuvusmassiivi väärtused määravad, millal funktsioon käivitatakse. Funktsioon käivitatakse uuesti ainult siis, kui need muutuvad.

Näiteks järgmisel rakenduse komponendil on meeldejäetud väärtus, mida nimetatakse tulemuseks.

importida { useMemo } alates "reageeri"
funktsiooniRakendus(väärtus) {
konst ruut = (väärtus) => {
tagasi väärtus * väärtus
}
konst tulemus = useMemo(
() => ruut (väärtus),
[ väärtus ]
);
tagasi (
<div>{tulemus (5)}</div>
)
}

Rakenduse komponent kutsub ruut() iga renderduse korral. Toimivus halveneb, kui rakenduse komponenti renderdatakse mitu korda Reageeri rekvisiidid muutmine või oleku värskendamine, eriti kui ruut() funktsioon on kallis.

Kuna aga useMemo() salvestab tagastatud väärtused vahemällu, ei käivitata ruutfunktsiooni iga kordusrenderduse korral, välja arvatud juhul, kui sõltuvusmassiivi argumendid muutuvad.

React.memo() kasutamine

React.memo() on kõrgemat järku komponent, mis aktsepteerib argumentidena Reacti komponenti ja funktsiooni. Funktsioon määrab, millal komponenti värskendada.

Funktsioon on valikuline ja kui seda ei pakuta, võrdleb React.memo komponendi praegusi rekvisiite selle eelmiste rekvisiitide madala koopiaga. Kui rekvisiidid on erinevad, käivitab see värskenduse. Kui rekvisiidid on samad, jätab see uuesti renderdamise vahele ja kasutab meeldejäetud väärtusi uuesti.

Valikuline funktsioon aktsepteerib argumentidena eelmisi ja järgmisi rekvisiite. Seejärel saate neid rekvisiite selgesõnaliselt võrrelda, et otsustada, kas komponenti värskendada või mitte.

Reageerige.memo(Komponent, [areEqual (prevProps, nextProps)])

Vaatame kõigepealt näidet ilma valikulise funktsiooni argumendita. Allpool on komponent nimega Kommentaarid, mis aktsepteerib nime ja e-posti rekvisiite.

funktsiooniKommentaarid ({nimi, kommentaar, meeldib}) {
tagasi (
<div>
<lk>{nimi}</lk>
<lk>{kommentaar}</lk>
<lk>{meeldib}</lk>
</div>
)
}

Mällu salvestatud kommentaaride komponendil on React.memo ümbritsetud järgmiselt:

konst MemoizedComment = React.memo (kommentaar)

Saate helistada ja seejärel helistada nagu igale teisele Reacti komponendile.

<MemoizedComment name="Maarja" kommentaar="Memorandum on suurepärane" meeldib=1/>

Kui soovite rekvisiitide võrdlemise ise läbi viia, edastage teise argumendina React.memo järgmine funktsioon.

importida Reageerige alates "reageeri"
funktsioonikontrollige CommentProps(prevProps, nextProps) {
tagasi prevProps.name nextProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes
}

konst MemoizedComment = React.memo (kommentaarid, checkCommentProps)

Kui checkProfileProps tagastab tõese, siis komponenti ei värskendata. Vastasel juhul renderdatakse see uuesti.

Kohandatud funktsioon on kasulik, kui soovite uuesti renderdamist kohandada. Näiteks saate seda kasutada kommentaaride komponendi värskendamiseks ainult siis, kui meeldimiste arv muutub.

Erinevalt konksust useMemo(), mis jätab meelde ainult funktsiooni tagastatud väärtuse, jätab React.memo meelde kogu funktsiooni.

Kasutage React.memo ainult puhaste komponentide jaoks. Samuti jäta võrdluskulude vähendamiseks meelde ainult need komponendid, mille rekvisiidid sageli muutuvad.

UseCallBack() kasutamine

Mälu salvestamiseks saate kasutada konksu useCallBack(). funktsiooni komponendid.

konst memoizedCallback = useCallback(
() => {
doSomething (a, b);
},
[a, b],
);

Funktsiooni värskendatakse ainult siis, kui sõltuvusmassiivi väärtused muutuvad. Konks töötab nagu useMemo() tagasikutse, kuid see jätab väärtuste meeldejätmise asemel meelde funktsiooni komponendi renderduste vahel.

Vaatleme järgmist näidet mällu salvestatud funktsioonist, mis kutsub API-d.

importida { useCallback, useEffect } alates "reageerida";
konst Komponent = () => {
konst getData = useCallback(() => {
console.log('helistage API-le');
}, []);
useEffect(() => {
getData();
}, [getData]);
};

Funktsiooni getData() funktsioonis useEffect kutsutakse uuesti välja ainult siis, kui getData väärtus muutub.

Kas peaksite meelde jätma?

Sellest õpetusest õppisite, mis on meeldejätmine, selle eelised ja kuidas seda JavaScriptis ja Reactis rakendada. Siiski peaksite teadma, et React on juba kiire. Enamikul juhtudel lisab komponentide või väärtuste meeldejätmine võrdluskulusid ega paranda jõudlust. Seetõttu jäta meelde ainult kallid komponendid.

React 18 tutvustas ka uusi konkse, nagu useId, useTransition ja useInsertionEffect. Saate neid kasutada Reacti rakenduste jõudluse ja kasutuskogemuse parandamiseks.