Uurige Reacti täiustatud memoiseerimistehnikaid globaalsete rakenduste jõudluse optimeerimiseks. Õppige, millal ja kuidas kasutada React.memo, useCallback, useMemo jpm.
React Memo: Sügavuti Globaalsete Rakenduste Optimeerimistehnikatesse
React on võimas JavaScripti teek kasutajaliideste loomiseks, kuid rakenduste keerukuse kasvades muutub jõudluse optimeerimine ülioluliseks. Üks oluline tööriist Reacti optimeerimiskomplektis on React.memo
. See blogipostitus pakub põhjalikku juhendit React.memo
ja sellega seotud tehnikate mõistmiseks ning tõhusaks kasutamiseks, et luua suure jõudlusega Reacti rakendusi globaalsele publikule.
Mis on React.memo?
React.memo
on kõrgema järgu komponent (HOC), mis memoiseerib funktsionaalse komponendi. Lihtsamalt öeldes takistab see komponendi uuesti renderdamist, kui selle prop'id pole muutunud. Vaikimisi teostab see prop'ide pinnapealse võrdluse. See võib märkimisväärselt parandada jõudlust, eriti komponentide puhul, mille renderdamine on arvutuslikult kulukas või mis renderdatakse sageli uuesti, isegi kui nende prop'id jäävad samaks.
Kujutage ette komponenti, mis kuvab kasutaja profiili. Kui kasutaja teave (nt nimi, avatar) pole muutunud, pole vaja komponenti uuesti renderdada. React.memo
võimaldab teil selle tarbetu uuesti renderdamise vahele jätta, säästes väärtuslikku protsessoriaega.
Miks kasutada React.memo?
Siin on peamised eelised React.memo
kasutamisel:
- Jõudluse parandamine: Hoiab ära tarbetud uuesti renderdamised, mis viib kiiremate ja sujuvamate kasutajaliidesteni.
- Vähendatud protsessori kasutus: Vähem uuesti renderdamisi tähendab väiksemat protsessori kasutust, mis on eriti oluline mobiilseadmete ja piiratud ribalaiusega piirkondade kasutajate jaoks.
- Parem kasutajakogemus: Reageerimisvõimelisem rakendus pakub paremat kasutajakogemust, eriti aeglasema internetiühenduse või vanemate seadmetega kasutajatele.
React.memo põhikäsklus
React.memo
kasutamine on lihtne. Lihtsalt mähkige oma funktsionaalne komponent sellesse:
import React from 'react';
const MyComponent = (props) => {
console.log('MyComponent renderdati');
return (
{props.data}
);
};
export default React.memo(MyComponent);
Selles näites renderdatakse MyComponent
uuesti ainult siis, kui data
prop muutub. console.log
lause aitab teil kontrollida, millal komponent tegelikult uuesti renderdatakse.
Pinnapealse võrdluse mõistmine
Vaikimisi teostab React.memo
prop'ide pinnapealse võrdluse. See tähendab, et see kontrollib, kas prop'ide viited on muutunud, mitte väärtused ise. See on oluline mõista objektide ja massiividega tegelemisel.
Vaatleme järgmist näidet:
import React, { useState } from 'react';
const MyComponent = (props) => {
console.log('MyComponent renderdati');
return (
{props.data.name}
);
};
const MemoizedComponent = React.memo(MyComponent);
const App = () => {
const [user, setUser] = useState({ name: 'John', age: 30 });
const handleClick = () => {
setUser({ ...user }); // Luuakse uus objekt samade väärtustega
};
return (
);
};
export default App;
Sel juhul, isegi kui user
objekti väärtused (name
ja age
) jäävad samaks, loob handleClick
funktsioon iga kord uue objektiviite, kui seda kutsutakse. Seetõttu näeb React.memo
, et data
prop on muutunud (kuna objektiviide on erinev) ja renderdab MyComponent
uuesti.
Kohandatud võrdlusfunktsioon
Et lahendada pinnapealse võrdluse probleemi objektide ja massiividega, võimaldab React.memo
teil teise argumendina esitada kohandatud võrdlusfunktsiooni. See funktsioon võtab kaks argumenti: prevProps
ja nextProps
. See peaks tagastama true
, kui komponent *ei tohiks* uuesti renderdada (st prop'id on tegelikult samad) ja false
, kui see peaks uuesti renderdama.
Siin on, kuidas saate eelmises näites kasutada kohandatud võrdlusfunktsiooni:
import React, { useState, memo } from 'react';
const MyComponent = (props) => {
console.log('MyComponent renderdati');
return (
{props.data.name}
);
};
const areEqual = (prevProps, nextProps) => {
return prevProps.data.name === nextProps.data.name && prevProps.data.age === nextProps.data.age;
};
const MemoizedComponent = memo(MyComponent, areEqual);
const App = () => {
const [user, setUser] = useState({ name: 'John', age: 30 });
const handleClick = () => {
setUser({ ...user });
};
return (
);
};
export default App;
Selles uuendatud näites võrdleb areEqual
funktsioon user
objektide name
ja age
omadusi. MemoizedComponent
renderdatakse nüüd uuesti ainult siis, kui name
või age
muutub.
Millal kasutada React.memo
React.memo
on kõige tõhusam järgmistes stsenaariumides:
- Komponendid, mis saavad sageli samu prop'e: Kui komponendi prop'id muutuvad harva, aitab
React.memo
kasutamine vältida tarbetuid uuesti renderdamisi. - Komponendid, mille renderdamine on arvutuslikult kulukas: Komponentide puhul, mis teostavad keerukaid arvutusi või renderdavad suuri andmehulki, võib uuesti renderdamiste vahelejätmine jõudlust märkimisväärselt parandada.
- Puhtad funktsionaalsed komponendid: Komponendid, mis toodavad sama sisendi jaoks sama väljundi, on ideaalsed kandidaadid
React.memo
jaoks.
Siiski on oluline märkida, et React.memo
ei ole imerohi. Selle valimatu kasutamine võib tegelikult jõudlust kahjustada, sest pinnapealsel võrdlusel endal on oma kulu. Seetõttu on ülioluline oma rakendust profileerida ja tuvastada komponendid, mis saaksid memoiseerimisest kõige rohkem kasu.
Alternatiivid React.memo-le
Kuigi React.memo
on võimas tööriist, pole see ainus võimalus Reacti komponentide jõudluse optimeerimiseks. Siin on mõned alternatiivid ja täiendavad tehnikad:
1. PureComponent
Klassikomponentide puhul pakub PureComponent
sarnast funktsionaalsust nagu React.memo
. See teostab nii prop'ide kui ka state'i pinnapealse võrdluse ja renderdab uuesti ainult siis, kui on muutusi.
import React from 'react';
class MyComponent extends React.PureComponent {
render() {
console.log('MyComponent renderdati');
return (
{this.props.data}
);
}
}
export default MyComponent;
PureComponent
on mugav alternatiiv shouldComponentUpdate
käsitsi rakendamisele, mis oli traditsiooniline viis klassikomponentides tarbetute uuesti renderdamiste vältimiseks.
2. shouldComponentUpdate
shouldComponentUpdate
on klassikomponentide elutsükli meetod, mis võimaldab teil määratleda kohandatud loogika otsustamiseks, kas komponent peaks uuesti renderdama. See pakub kõige rohkem paindlikkust, kuid nõuab ka rohkem käsitsi tööd.
import React from 'react';
class MyComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return nextProps.data !== this.props.data;
}
render() {
console.log('MyComponent renderdati');
return (
{this.props.data}
);
}
}
export default MyComponent;
Kuigi shouldComponentUpdate
on endiselt saadaval, eelistatakse üldiselt PureComponent
i ja React.memo
d nende lihtsuse ja kasutusmugavuse tõttu.
3. useCallback
useCallback
on Reacti hook, mis memoiseerib funktsiooni. See tagastab funktsiooni memoiseeritud versiooni, mis muutub ainult siis, kui mõni selle sõltuvustest on muutunud. See on eriti kasulik tagasikutsete (callbacks) edastamisel prop'idena memoiseeritud komponentidele.
Vaatleme järgmist näidet:
import React, { useState, useCallback, memo } from 'react';
const MyComponent = (props) => {
console.log('MyComponent renderdati');
return (
);
};
const MemoizedComponent = memo(MyComponent);
const App = () => {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
Count: {count}
);
};
export default App;
Selles näites tagab useCallback
, et handleClick
funktsioon muutub ainult siis, kui count
state muutub. Ilma useCallback
ita loodaks App
i igal renderdamisel uus funktsioon, mis põhjustaks MemoizedComponent
i tarbetu uuesti renderdamise.
4. useMemo
useMemo
on Reacti hook, mis memoiseerib väärtuse. See tagastab memoiseeritud väärtuse, mis muutub ainult siis, kui mõni selle sõltuvustest on muutunud. See on kasulik kulukate arvutuste vältimiseks, mida ei pea igal renderdamisel uuesti käivitama.
import React, { useState, useMemo } from 'react';
const App = () => {
const [input, setInput] = useState('');
const expensiveCalculation = (str) => {
console.log('Arvutan...');
let result = 0;
for (let i = 0; i < str.length * 1000000; i++) {
result++;
}
return result;
};
const memoizedResult = useMemo(() => expensiveCalculation(input), [input]);
return (
setInput(e.target.value)} />
Result: {memoizedResult}
);
};
export default App;
Selles näites tagab useMemo
, et expensiveCalculation
funktsioon kutsutakse välja ainult siis, kui input
state muutub. See takistab arvutuse uuesti käivitamist igal renderdamisel, mis võib jõudlust märkimisväärselt parandada.
Praktilised näited globaalsete rakenduste jaoks
Vaatleme mõningaid praktilisi näiteid, kuidas React.memo
ja sellega seotud tehnikaid saab rakendada globaalsetes rakendustes:
1. Keelevalija
Keelevalija komponent renderdab sageli saadaolevate keelte loendi. See loend võib olla suhteliselt staatiline, mis tähendab, et see ei muutu sageli. React.memo
kasutamine aitab vältida keelevalija tarbetut uuesti renderdamist, kui rakenduse teised osad uuenevad.
import React, { memo } from 'react';
const LanguageItem = ({ language, onSelect }) => {
console.log(`LanguageItem ${language} renderdati`);
return (
onSelect(language)}>{language}
);
};
const MemoizedLanguageItem = memo(LanguageItem);
const LanguageSelector = ({ languages, onSelect }) => {
return (
{languages.map((language) => (
))}
);
};
export default LanguageSelector;
Selles näites renderdatakse MemoizedLanguageItem
uuesti ainult siis, kui language
või onSelect
prop muutub. See võib olla eriti kasulik, kui keeleloend on pikk või kui onSelect
käsitleja on keeruline.
2. Valuutakonverter
Valuutakonverteri komponent võib kuvada valuutade loendi ja nende vahetuskursid. Vahetuskursse võidakse perioodiliselt uuendada, kuid valuutade loend võib jääda suhteliselt stabiilseks. React.memo
kasutamine aitab vältida valuutaloendi tarbetut uuesti renderdamist, kui vahetuskursid uuenevad.
import React, { memo } from 'react';
const CurrencyItem = ({ currency, rate, onSelect }) => {
console.log(`CurrencyItem ${currency} renderdati`);
return (
onSelect(currency)}>{currency} - {rate}
);
};
const MemoizedCurrencyItem = memo(CurrencyItem);
const CurrencyConverter = ({ currencies, onSelect }) => {
return (
{Object.entries(currencies).map(([currency, rate]) => (
))}
);
};
export default CurrencyConverter;
Selles näites renderdatakse MemoizedCurrencyItem
uuesti ainult siis, kui currency
, rate
või onSelect
prop muutub. See võib parandada jõudlust, kui valuutaloend on pikk või kui vahetuskursside uuendused on sagedased.
3. Kasutajaprofiili kuvamine
Kasutajaprofiili kuvamine hõlmab staatilise teabe näitamist, nagu nimi, profiilipilt ja potentsiaalselt elulugu. `React.memo` kasutamine tagab, et komponent renderdatakse uuesti ainult siis, kui kasutaja andmed tegelikult muutuvad, mitte iga vanemkomponendi uuenduse korral.
import React, { memo } from 'react';
const UserProfile = ({ user }) => {
console.log('UserProfile renderdati');
return (
{user.name}
{user.bio}
);
};
export default memo(UserProfile);
See on eriti kasulik, kui `UserProfile` on osa suuremast, sageli uuenevast armatuurlauast või rakendusest, kus kasutaja andmed ise sageli ei muutu.
Levinumad lõksud ja kuidas neid vältida
Kuigi React.memo
on väärtuslik optimeerimistööriist, on oluline olla teadlik levinud lõksudest ja sellest, kuidas neid vältida:
- Ülemäärane memoiseerimine:
React.memo
valimatu kasutamine võib tegelikult jõudlust kahjustada, sest pinnapealsel võrdlusel endal on oma kulu. Memoiseerige ainult komponente, mis sellest tõenäoliselt kasu saavad. - Valed sõltuvusmassiivid:
useCallback
i jauseMemo
kasutamisel veenduge, et pakute õigeid sõltuvusmassiive. Sõltuvuste väljajätmine või tarbetute sõltuvuste lisamine võib põhjustada ootamatut käitumist ja jõudlusprobleeme. - Prop'ide muteerimine: Vältige prop'ide otsest muteerimist, kuna see võib mööda minna
React.memo
pinnapealsest võrdlusest. Prop'ide uuendamisel looge alati uued objektid või massiivid. - Keeruline võrdlusloogika: Vältige keerulist võrdlusloogikat kohandatud võrdlusfunktsioonides, kuna see võib tühistada
React.memo
jõudluseelised. Hoidke võrdlusloogika võimalikult lihtne ja tõhus.
Oma rakenduse profileerimine
Parim viis kindlaks teha, kas React.memo
tegelikult jõudlust parandab, on oma rakenduse profileerimine. React pakub mitmeid tööriistu profileerimiseks, sealhulgas React DevTools Profiler ja React.Profiler
API.
React DevTools Profiler võimaldab teil salvestada oma rakenduse jõudluse jälgi ja tuvastada komponente, mis renderdatakse sageli uuesti. React.Profiler
API võimaldab teil programmiliselt mõõta konkreetsete komponentide renderdamisaega.
Oma rakendust profileerides saate tuvastada komponendid, mis saaksid memoiseerimisest kõige rohkem kasu, ja tagada, et React.memo
tegelikult parandab jõudlust.
Kokkuvõte
React.memo
on võimas tööriist Reacti komponentide jõudluse optimeerimiseks. Vältides tarbetuid uuesti renderdamisi, võib see parandada teie rakenduste kiirust ja reageerimisvõimet, mis viib parema kasutajakogemuseni. Siiski on oluline kasutada React.memo
d arukalt ja profileerida oma rakendust, et tagada selle tegelik jõudluse parandamine.
Selles blogipostituses käsitletud kontseptsioone ja tehnikaid mõistes saate tõhusalt kasutada React.memo
d ja sellega seotud tehnikaid, et luua suure jõudlusega Reacti rakendusi globaalsele publikule, tagades, et teie rakendused on kiired ja reageerimisvõimelised kasutajatele üle kogu maailma.
Pidage meeles, et Reacti rakenduste optimeerimisel tuleb arvestada globaalsete teguritega, nagu võrgu latentsusaeg ja seadme võimekus. Keskendudes jõudlusele ja ligipääsetavusele, saate luua rakendusi, mis pakuvad suurepärast kogemust kõigile kasutajatele, olenemata nende asukohast või seadmest.