Memoisering er en optimaliseringsteknikk som ligner på caching. Det fungerer ved å lagre de tidligere resultatene av et funksjonskall og bruke disse resultatene neste gang funksjonen kjøres. Det er spesielt nyttig i beregningstunge apper som gjentar funksjonsanrop på de samme parameterne.
Du kan bruke memoisering i vanlig JavaScript og også i React, på noen forskjellige måter.
Memoisering i JavaScript
For å huske en funksjon i JavaScript, må du lagre resultatene av denne funksjonen i en hurtigbuffer. Cachen kan være et objekt med argumentene som nøkler og resultater som verdier.
Når du kaller denne funksjonen, sjekker den først om resultatet er tilstede i cachen før den kjøres. Hvis det er det, returnerer den de bufrede resultatene. Ellers utføres den.
Tenk på denne funksjonen:
funksjontorget(num) {
komme tilbake num * num
}
Funksjonen tar inn et argument og returnerer kvadratet.
For å kjøre funksjonen, ring den med et nummer som dette:
torget(5) // 25
Med 5 som argument, vil square() løpe ganske fort. Men hvis du skulle beregne kvadratet på 70 000, ville det være en merkbar forsinkelse. Ikke mye, men en forsinkelse likevel. Nå, hvis du skulle ringe funksjonen flere ganger og passere 70 000, ville du oppleve en forsinkelse i hver samtale.
Du kan eliminere denne forsinkelsen ved å bruke memoisering.
konst memoizedSquare = () => {
la cache = {};
komme tilbake (antall) => {
hvis (tall in cache) {
console.log('Gjenbruker bufret verdi');
komme tilbake cache[num];
} ellers {
console.log('Beregner resultat');
la resultat = num * num;
// cache de nyresultatverditilnestetid
cache[num] = resultat;
komme tilbake resultat;
}
}
}
I dette eksemplet sjekker funksjonen om den har beregnet resultatet før, ved å sjekke om den finnes i cache-objektet. Hvis den har den, returnerer den den allerede beregnede verdien.
Når funksjonen mottar et nytt tall, beregner den en ny verdi og lagrer resultatene i hurtigbufferen før den returnerer.
Igjen er dette eksemplet ganske enkelt, men det forklarer hvordan memoisering vil fungere for å forbedre ytelsen til et program.
Du bør bare huske rene funksjoner. Disse funksjonene returnerer det samme resultatet når du sender de samme argumentene inn. Hvis du bruker memoisering på urene funksjoner, vil du ikke forbedre ytelsen, men øke overheaden. Det er fordi du velger hastighet fremfor minne hver gang du lagrer en funksjon.
Memoisering i React
Hvis du ønsker å optimalisere React-komponenter, gir React memoisering gjennom useMemo()-kroken, React.memo og useCallBack().
Bruke useMemo()
useMemo() er en Reagerkrok som aksepterer en funksjon og en avhengighetsmatrise.
konst memoizedValue = useMemo(() => computeExpensiveValue (a, b), [a, b]);
Den lagrer verdien som returneres fra den funksjonen. Verdiene i avhengighetsmatrisen dikterer når funksjonen utføres. Først når de endres, utføres funksjonen igjen.
For eksempel har følgende app-komponent en lagret verdi kalt resultat.
import { useMemo } fra "reagere"
funksjonApp(verdi) {
konst kvadrat = (verdi) => {
komme tilbake verdi * verdi
}
konst resultat = brukMemo(
() => kvadrat (verdi),
[ verdi ]
);
komme tilbake (
<div>{resultat (5)}</div>
)
}
App-komponenten kaller square() på hver gjengivelse. Ytelsen vil forringes hvis App-komponenten gjengis mange ganger pga Reager rekvisitter endring eller tilstandsoppdatering, spesielt hvis square()-funksjonen er dyr.
Siden useMemo() bufrer de returnerte verdiene, blir ikke kvadratfunksjonen utført i hver gjengivelse med mindre argumentene i avhengighetsmatrisen endres.
Bruke React.memo()
React.memo() er en høyere ordens komponent som godtar en React-komponent og en funksjon som argumenter. Funksjonen bestemmer når komponenten skal oppdateres.
Funksjonen er valgfri, og hvis den ikke er gitt, gjør React.memo en grunn kopi sammenligning av komponentens nåværende rekvisitter med dens tidligere rekvisitter. Hvis rekvisittene er forskjellige, utløser det en oppdatering. Hvis rekvisittene er de samme, hopper den over gjengivelsen og gjenbruker de lagrede verdiene.
Den valgfrie funksjonen godtar de forrige rekvisittene og de neste rekvisittene som argumenter. Du kan deretter eksplisitt sammenligne disse rekvisittene for å bestemme om du skal oppdatere komponenten eller ikke.
Reagere.memo(Komponent, [areEqual (prevProps, nextProps)])
La oss først se på et eksempel uten det valgfrie funksjonsargumentet. Nedenfor er en komponent kalt Kommentarer som godtar navn og e-postrekvisitter.
funksjonKommentarer ({navn, kommentar, liker}) {
komme tilbake (
<div>
<s>{Navn}</s>
<s>{kommentar}</s>
<s>{liker}</s>
</div>
)
}
Den memorerte kommentarkomponenten vil ha React.memo pakket rundt seg slik:
konst MemoizedComment = React.memo (Kommentar)
Du kan ringe og kalle det som alle andre React-komponenter.
<MemoizedComment name="Mary" kommentar="Memoisering er flott" liker=1/>
Hvis du ønsker å utføre rekvisittsammenligningen selv, send følgende funksjon til React.memo som det andre argumentet.
import Reagere fra "reagere"
funksjonsjekkCommentProps(prevProps, nextProps) {
komme tilbake prevProps.name nesteProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes
}
konst MemoizedComment = React.memo (Kommentarer, sjekkCommentProps)
Hvis checkProfileProps returnerer true, oppdateres ikke komponenten. Ellers blir den gjengitt på nytt.
Den egendefinerte funksjonen er nyttig når du vil tilpasse gjengivelsen. Du kan for eksempel bruke den til å oppdatere Kommentarer-komponenten bare når antallet liker endres.
I motsetning til useMemo()-kroken som husker bare den returnerte verdien av en funksjon, lagrer React.memo hele funksjonen.
Bruk React.memo kun for rene komponenter. For å redusere sammenligningskostnadene må du bare huske komponenter hvis rekvisitter endres ofte.
Bruke useCallBack()
Du kan bruke useCallBack()-kroken til å huske funksjonskomponenter.
konst memoizedCallback = useCallback(
() => {
gjøre Noe (a, b);
},
[a, b],
);
Funksjonen oppdateres bare når verdiene i avhengighetsmatrisen endres. Kroken fungerer som useMemo()-tilbakekallingen, men den lagrer funksjonskomponenten mellom gjengivelser i stedet for å huske verdier.
Tenk på følgende eksempel på en memoisert funksjon som kaller et API.
import { useCallback, useEffect } fra "reagere";
konst Komponent = () => {
konst getData = useCallback(() => {
console.log('kall et API');
}, []);
useEffect(() => {
getData();
}, [getData]);
};
GetData()-funksjonen kalt i useEffect kalles opp igjen bare når getData-verdien endres.
Bør du huske?
I denne opplæringen lærte du hva memoisering er, dens fordeler og hvordan du implementerer den i JavaScript og React. Du bør imidlertid vite at React allerede er rask. I de fleste tilfeller øker det å huske komponenter eller verdier til sammenligningskostnader og forbedrer ikke ytelsen. På grunn av dette må du bare huske dyre komponenter.
React 18 introduserte også nye kroker som useId, useTransition og useInsertionEffect. Du kan bruke disse til å forbedre ytelsen og brukeropplevelsen til React-applikasjoner.