A memoization egy optimalizálási technika, hasonlóan a gyorsítótárazáshoz. Úgy működik, hogy eltárolja a függvényhívás korábbi eredményeit, és ezeket az eredményeket használja a függvény következő futtatásakor. Különösen hasznos a számításigényes alkalmazásokban, amelyek ugyanazokkal a paraméterekkel ismétlik meg a függvényhívásokat.
A memoizációt használhatja egyszerű JavaScriptben és a Reactban is, néhány különböző módon.
Memoizáció JavaScriptben
Ahhoz, hogy megjegyezzen egy függvényt JavaScriptben, a függvény eredményeit a gyorsítótárban kell tárolnia. A gyorsítótár lehet egy objektum, amelyben az argumentumok kulcsok, az eredmények pedig értékek.
Amikor meghívja ezt a függvényt, a futtatás előtt először ellenőrzi, hogy az eredmény megtalálható-e a gyorsítótárban. Ha igen, akkor a gyorsítótárazott eredményeket adja vissza. Ellenkező esetben végrehajtja.
Fontolja meg ezt a funkciót:
funkciónégyzet(sz) {
Visszatérés szám * szám
}
A függvény bevesz egy argumentumot, és visszaadja a négyzetét.
A funkció futtatásához hívja meg egy ilyen számmal:
négyzet(5) // 25
Ha az 5 az argumentum, a square() elég gyorsan fog futni. Ha azonban kiszámolná a 70 000-es négyzetet, akkor észrevehető késés következne be. Nem sokat, de késéssel mégis. Most, ha többször hívná meg a függvényt, és átadná a 70 000-et, akkor minden hívásnál késést tapasztalna.
Ezt a késleltetést kiküszöbölheti a memoizálással.
const memoizedSquare = () => {
hagyja gyorsítótár = {};
Visszatérés (szám) => {
if (szám be gyorsítótár) {
console.log('A gyorsítótárazott érték újrafelhasználása');
Visszatérés gyorsítótár[sz];
} más {
console.log('Az eredmény kiszámítása');
hagyja eredmény = szám * szám;
// gyorsítótár az újeredményértékszámárakövetkezőidő
gyorsítótár[sz] = eredmény;
Visszatérés eredmény;
}
}
}
Ebben a példában a függvény ellenőrzi, hogy korábban kiszámította-e az eredményt, és ellenőrzi, hogy létezik-e a cache objektumban. Ha van, akkor a már kiszámított értéket adja vissza.
Amikor a függvény új számot kap, új értéket számol, és az eredményeket a gyorsítótárban tárolja, mielőtt visszatérne.
Ez a példa ismét nagyon egyszerű, de elmagyarázza, hogyan működne a memoizálás a program teljesítményének javítása érdekében.
Csak tiszta függvényeket szabad megjegyeznie. Ezek a függvények ugyanazt az eredményt adják vissza, ha ugyanazokat az argumentumokat adja át. Ha szennyezett funkciókhoz memoizálást használ, akkor nem javítja a teljesítményt, hanem növeli a rezsiköltséget. Ennek az az oka, hogy a memória helyett a sebességet választja minden alkalommal, amikor megjegyzi egy függvényt.
Memoizáció a Reactban
Ha optimalizálni szeretné a React összetevőit, a React a useMemo() hook, a React.memo és a useCallBack() segítségével biztosít memogatást.
A useMemo() használata
A useMemo() a Reagálás horog amely elfogad egy függvényt és egy függőségi tömböt.
const memoizedValue = useMemo(() => computeExpensiveValue (a, b), [a, b]);
Megjegyzi az adott függvénytől visszaadott értéket. A függőségi tömbben lévő értékek határozzák meg, hogy a függvény mikor kerül végrehajtásra. Csak akkor hajtják végre újra a függvényt, ha megváltoznak.
Például a következő alkalmazás-összetevőnek van egy eredmény nevű memorizált értéke.
import { useMemo } tól től "reagál"
funkcióApp(érték) {
const négyzet = (érték) => {
Visszatérés érték * érték
}
const eredmény = useMemo(
() => négyzet (érték),
[ érték ]
);
Visszatérés (
<div>{eredmény (5)}</div>
)
}
Az App komponens minden renderelésnél meghívja a square() függvényt. A teljesítmény romlik, ha az App komponenst többször rendereli a következő miatt React kellékek módosítása vagy állapotfrissítése, különösen, ha a square() függvény drága.
Mivel azonban a useMemo() gyorsítótárazza a visszaadott értékeket, a négyzetes függvény nem kerül végrehajtásra minden újramegjelenítéskor, hacsak a függőségi tömb argumentumai nem változnak.
A React.memo() használata
A React.memo() egy magasabb rendű komponens, amely egy React komponenst és egy függvényt fogad el argumentumként. A funkció határozza meg, hogy mikor kell frissíteni az összetevőt.
A funkció nem kötelező, és ha nincs megadva, a React.memo egy sekély másolatot készít az összetevő jelenlegi kellékeiről a korábbi kellékekkel. Ha a kellékek eltérőek, akkor frissítést indít el. Ha a kellékek megegyeznek, akkor kihagyja az újrarenderelést, és újra felhasználja a memorandum értékeket.
Az opcionális függvény argumentumként elfogadja az előző és a következő kellékeket. Ezután kifejezetten összehasonlíthatja ezeket a kellékeket, hogy eldöntse, frissítse-e az összetevőt vagy sem.
Reagál.Memo(Összetevő, [areEqual (prevProps, nextProps)])
Nézzünk először egy példát az opcionális függvény argumentum nélkül. Az alábbiakban található egy Comments nevű komponens, amely elfogadja a nevet és az e-mail-reklámokat.
funkcióHozzászólások ({név, megjegyzés, kedvelések}) {
Visszatérés (
<div>
<p>{név}</p>
<p>{megjegyzés}</p>
<p>{tetszik}</p>
</div>
)
}
A megjegyzett megjegyzések komponense körül a React.memo a következőképpen kerül körbe:
const MemoizedComment = React.memo (Megjegyzés)
Hívhatja, majd hívhatja, mint bármely más React összetevőt.
<MemoizedComment name="Mary" komment="Az emlékezés nagyszerű" likes=1/>
Ha saját maga szeretné elvégezni a kellékek összehasonlítását, adja át a következő függvényt a React.memo-nak második argumentumként.
import Reagál tól től "reagál"
funkciócheckCommentProps(prevProps, nextProps) {
Visszatérés prevProps.name nextProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes
}
const MemoizedComment = React.memo (Megjegyzések, checkCommentProps)
Ha a checkProfileProps true értéket ad vissza, akkor az összetevő nem frissül. Ellenkező esetben a rendszer újra rendereli.
Az egyéni funkció akkor hasznos, ha testre szeretné szabni az újrarenderelést. Például csak akkor frissítheti a Megjegyzések összetevőt, ha a kedvelések száma megváltozik.
A useMemo() hooktól eltérően, amely csak a függvény visszaadott értékét jegyzi meg, a React.memo az egész függvényt megjegyzi.
Csak tiszta alkatrészekhez használja a React.memo-t. Ezenkívül az összehasonlítási költségek csökkentése érdekében csak azokat az alkatrészeket jegyezze meg, amelyek kellékei gyakran változnak.
A useCallBack() használata
Használhatja a useCallBack() hook-ot a memorozáshoz funkció összetevői.
const memoizedCallback = useCallback(
() => {
doSomething (a, b);
},
[a, b],
);
A függvény csak akkor frissül, ha a függőségi tömb értékei megváltoznak. A hook úgy működik, mint a useMemo() visszahívás, de az értékek memorizálása helyett megjegyzi a függvénykomponenst a megjelenítések között.
Tekintsük a következő példát egy memoizált függvényre, amely API-t hív meg.
import { useCallback, useEffect } tól től "reagál";
const Összetevő = () => {
const getData = useCallback(() => {
console.log('hívjon egy API-t');
}, []);
useEffect(() => {
getData();
}, [getData]);
};
A useEffect-ben meghívott getData() függvény csak akkor kerül újrahívásra, ha a getData érték megváltozik.
Emlékeztetni kell?
Ebben az oktatóanyagban megtanulta, mi az a memoizáció, annak előnyei, valamint a JavaScript és a React alkalmazásban való megvalósítása. Tudnia kell azonban, hogy a React már gyors. A legtöbb esetben az összetevők vagy értékek memorizálása az összehasonlítási költségeket növeli, és nem javítja a teljesítményt. Emiatt csak a drága alkatrészeket jegyezze meg.
A React 18 új horgokat is bevezetett, mint például a useId, a useTransition és a useInsertionEffect. Ezek segítségével javíthatja a React alkalmazások teljesítményét és felhasználói élményét.