Memoiseren is een optimalisatietechniek, vergelijkbaar met caching. Het werkt door de eerdere resultaten van een functieaanroep op te slaan en die resultaten te gebruiken de volgende keer dat de functie wordt uitgevoerd. Het is vooral handig in rekenintensieve apps die functieaanroepen herhalen op dezelfde parameters.
U kunt memo's op verschillende manieren gebruiken in gewoon JavaScript en ook in React.
Memorisatie in JavaScript
Om een functie in JavaScript te onthouden, moet u de resultaten van die functie in een cache opslaan. De cache kan een object zijn met de argumenten als sleutels en resultaten als waarden.
Wanneer u deze functie aanroept, controleert deze eerst of het resultaat in de cache aanwezig is voordat deze wordt uitgevoerd. Als dit het geval is, worden de resultaten in de cache geretourneerd. Anders wordt het uitgevoerd.
Overweeg deze functie:
functievierkant(aantal) {
opbrengst aantal * aantal
}
De functie neemt een argument op en retourneert het kwadraat ervan.
Om de functie uit te voeren, roept u deze aan met een nummer zoals dit:
vierkant(5) // 25
Met 5 als argument, zal square() behoorlijk snel lopen. Als u echter het kwadraat van 70.000 zou berekenen, zou er een merkbare vertraging zijn. Niet veel, maar toch een vertraging. Als u de functie nu meerdere keren zou aanroepen en de 70.000 zou passeren, zou u bij elke aanroep een vertraging ervaren.
U kunt deze vertraging elimineren met behulp van geheugenopslag.
const memoizedSquare = () => {
laten cache = {};
opbrengst (getal) => {
als (num in cache) {
console.log('Gecachte waarde opnieuw gebruiken');
opbrengst cache[aantal];
} anders {
console.log('Resultaat berekenen');
laten resultaat = aantal * aantal;
// cache de nieuweresultaatwaardevoorDe volgendetijd
cache[aantal] = resultaat;
opbrengst resultaat;
}
}
}
In dit voorbeeld controleert de functie of het resultaat eerder is berekend door te controleren of het in het cache-object bestaat. Als dit het geval is, wordt de reeds berekende waarde geretourneerd.
Wanneer de functie een nieuw getal ontvangt, berekent deze een nieuwe waarde en slaat de resultaten op in de cache voordat deze terugkeert.
Nogmaals, dit voorbeeld is vrij eenvoudig, maar het legt uit hoe het opslaan van herinneringen zou werken om de prestaties van een programma te verbeteren.
U moet alleen pure functies onthouden. Deze functies retourneren hetzelfde resultaat wanneer u dezelfde argumenten doorgeeft. Als u memo's gebruikt voor onzuivere functies, verbetert u de prestaties niet, maar verhoogt u uw overhead. Dat komt omdat je elke keer dat je een functie opslaat snelheid boven geheugen kiest.
Memoriseren in Reageren
Als je React-componenten wilt optimaliseren, biedt React memo-opslag via de useMemo() hook, React.memo en useCallBack().
UseMemo() gebruiken
useMemo() is een Reageerhaak die een functie en een afhankelijkheidsmatrix accepteert.
const memoizedValue = useMemo(() => computeExpensiveValue (a, b), [a, b]);
Het onthoudt de waarde die door die functie wordt geretourneerd. De waarden in de afhankelijkheidsmatrix bepalen wanneer de functie wordt uitgevoerd. Pas als ze veranderen, wordt de functie opnieuw uitgevoerd.
De volgende app-component heeft bijvoorbeeld een opgeslagen waarde met de naam resultaat.
importeren { gebruikMemo } van "Reageer"
functieApp(waarde) {
const vierkant = (waarde) => {
opbrengst waarde * waarde
}
const resultaat = gebruikMemo(
() => vierkant (waarde),
[ waarde ]
);
opbrengst (
<div>{resultaat (5)}</div>
)
}
De App-component roept square() aan op elke render. De prestaties zullen afnemen als de App-component vele malen wordt gerenderd vanwege: Reageer rekwisieten wijzigen of bijwerken van de status, vooral als de functie square() duur is.
Aangezien useMemo() de geretourneerde waarden echter in de cache opslaat, wordt de kwadraatfunctie niet bij elke nieuwe weergave uitgevoerd, tenzij de argumenten in de afhankelijkheidsarray veranderen.
React.memo() gebruiken
React.memo() is een component van hogere orde die een React-component en een functie als argumenten accepteert. De functie bepaalt wanneer het onderdeel moet worden bijgewerkt.
De functie is optioneel en indien niet voorzien, maakt React.memo een oppervlakkige vergelijking van de huidige rekwisieten van de component met de vorige rekwisieten. Als de rekwisieten anders zijn, wordt een update geactiveerd. Als de rekwisieten hetzelfde zijn, wordt het opnieuw renderen overgeslagen en worden de opgeslagen waarden opnieuw gebruikt.
De optionele functie accepteert de vorige rekwisieten en de volgende rekwisieten als argumenten. U kunt deze rekwisieten dan expliciet vergelijken om te beslissen of u de component wilt bijwerken of niet.
Reageer.memo(onderdeel, [areEqual (prevProps, nextProps)])
Laten we eerst naar een voorbeeld kijken zonder het optionele functieargument. Hieronder vindt u een component met de naam Opmerkingen die de naam en e-mailprops accepteert.
functieOpmerkingen ({naam, opmerking, vind-ik-leuks}) {
opbrengst (
<div>
<p>{naam}</p>
<p>{opmerking}</p>
<p>{vind ik leuk}</p>
</div>
)
}
De in het geheugen opgeslagen commentaarcomponent heeft React.memo er als volgt omheen gewikkeld:
const MemoizedComment = React.memo (Commentaar)
Je kunt het dan bellen zoals elk ander React-component.
<MemoizedComment name="Maria" comment="Memoriseren is geweldig" vind-ik-leuks=1/>
Als je de rekwisietenvergelijking zelf wilt uitvoeren, geef dan de volgende functie door aan React.memo als het tweede argument.
importeren Reageer van "Reageer"
functiecheckOpmerkingProps(prevProps, nextProps) {
opbrengst prevProps.name nextProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes
}
const MemoizedComment = React.memo (opmerkingen, checkCommentProps)
Als checkProfileProps true retourneert, wordt het onderdeel niet bijgewerkt. Anders wordt het opnieuw weergegeven.
De aangepaste functie is handig wanneer u de re-render wilt aanpassen. U kunt het bijvoorbeeld gebruiken om de component Opmerkingen alleen bij te werken wanneer het aantal vind-ik-leuks verandert.
In tegenstelling tot de useMemo() hook die alleen de geretourneerde waarde van een functie onthoudt, onthoudt React.memo de hele functie.
Gebruik React.memo alleen voor pure componenten. Om de vergelijkingskosten te verlagen, moet u ook alleen componenten onthouden waarvan de rekwisieten vaak veranderen.
useCallBack() gebruiken
U kunt de useCallBack() hook gebruiken om te onthouden functie componenten.
const memoizedCallback = gebruikCallback(
() => {
iets doen (a, b);
},
[a, b],
);
De functie wordt alleen bijgewerkt wanneer de waarden in de afhankelijkheidsmatrix veranderen. De hook werkt als de useMemo() callback, maar het onthoudt de functiecomponent tussen renders in plaats van waarden te onthouden.
Bekijk het volgende voorbeeld van een in het geheugen opgeslagen functie die een API aanroept.
importeren { useCallback, useEffect } van "Reageer";
const Onderdeel = () => {
const getData = useCallback(() => {
console.log('een API aanroepen');
}, []);
gebruikEffect(() => {
gegevens verkrijgen();
}, [gegevens verkrijgen]);
};
De functie getData() die in useEffect wordt aangeroepen, wordt alleen opnieuw aangeroepen als de waarde getData verandert.
Moet je onthouden?
In deze tutorial heb je geleerd wat memoization is, de voordelen ervan en hoe je het in JavaScript en React kunt implementeren. U moet echter weten dat React al snel is. In de meeste gevallen voegt het onthouden van componenten of waarden vergelijkingskosten toe en verbetert het de prestaties niet. Onthoud daarom alleen dure componenten.
React 18 introduceerde ook nieuwe hooks zoals useId, useTransition en useInsertionEffect. U kunt deze gebruiken om de prestaties en gebruikerservaring van React-applicaties te verbeteren.