Põhjalik juhend Reacti rakenduste optimeerimiseks, vältides mittevajalikke uuesti renderdamisi. Õppige memoiseerimist, PureComponenti ja muid tehnikaid.
Reacti renderdamise optimeerimine: mittevajalike uuesti renderdamiste ennetamise meisterlikkus
React, võimas JavaScripti teek kasutajaliideste loomiseks, võib mõnikord kannatada jõudluse kitsaskohtade all, mis on tingitud liigsetest või mittevajalikest uuesti renderdamistest. Keerulistes rakendustes, kus on palju komponente, võivad need uuesti renderdamised oluliselt halvendada jõudlust, põhjustades loiut kasutajakogemust. See juhend pakub põhjalikku ülevaadet tehnikatest, kuidas vältida mittevajalikke uuesti renderdamisi Reactis, tagades, et teie rakendused on kiired, tõhusad ja reageerivad kasutajatele üle maailma.
Uuesti renderdamiste mõistmine Reactis
Enne optimeerimistehnikatesse süvenemist on oluline mõista, kuidas Reacti renderdamisprotsess toimib. Kui komponendi olek (state) või omadused (props) muutuvad, käivitab React selle komponendi ja selle laste uuesti renderdamise. See protsess hõlmab virtuaalse DOM-i uuendamist ja selle võrdlemist eelmise versiooniga, et määrata minimaalne muudatuste hulk, mida tegelikule DOM-ile rakendada.
Siiski ei nõua kõik oleku või omaduste muudatused DOM-i uuendamist. Kui uus virtuaalne DOM on identne eelmisega, on uuesti renderdamine sisuliselt ressursside raiskamine. Need mittevajalikud uuesti renderdamised kulutavad väärtuslikke protsessori tsükleid ja võivad põhjustada jõudlusprobleeme, eriti keeruliste komponendipuudega rakendustes.
Mittevajalike uuesti renderdamiste tuvastamine
Esimene samm uuesti renderdamiste optimeerimisel on tuvastada, kus need toimuvad. React pakub selleks mitmeid tööriistu:
1. Reacti profiilija
Reacti profiilija, mis on saadaval React DevTools laiendusena Chrome'ile ja Firefoxile, võimaldab teil salvestada ja analüüsida oma Reacti komponentide jõudlust. See annab ülevaate sellest, millised komponendid uuesti renderdavad, kui kaua nende renderdamine aega võtab ja miks nad uuesti renderdavad.
Profiilija kasutamiseks klõpsake lihtsalt DevTools'is nuppu "Record" ja suhelge oma rakendusega. Pärast salvestamist kuvab profiilija leekgraafiku, mis visualiseerib komponendipuu ja selle renderdamisajad. Komponendid, mille renderdamine võtab kaua aega või mis renderdavad sageli uuesti, on peamised optimeerimiskandidaadid.
2. Why Did You Render?
"Why Did You Render?" on teek, mis paigaldab Reactile plaastri, et teavitada teid potentsiaalselt mittevajalikest uuesti renderdamistest, logides konsooli konkreetsed omadused (props), mis uuesti renderdamise põhjustasid. See võib olla äärmiselt kasulik uuesti renderdamise probleemide algpõhjuste väljaselgitamisel.
"Why Did You Render?" kasutamiseks installige see arendussõltuvusena:
npm install @welldone-software/why-did-you-render --save-dev
Seejärel importige see oma rakenduse sisendpunkti (nt index.js):
import whyDidYouRender from '@welldone-software/why-did-you-render';
if (process.env.NODE_ENV === 'development') {
whyDidYouRender(React, {
include: [/.*/]
});
}
See kood lubab "Why Did You Render?" arendusreĹľiimis ja logib konsooli teavet potentsiaalselt mittevajalike uuesti renderdamiste kohta.
3. Console.log laused
Lihtne, kuid tõhus tehnika on lisada console.log
lauseid oma komponendi render
meetodisse (või funktsionaalse komponendi kehasse), et jälgida, millal see uuesti renderdab. Kuigi see on vähem keerukas kui profiilija või "Why Did You Render?", võib see kiiresti esile tuua komponente, mis renderdavad oodatust sagedamini uuesti.
Tehnikad mittevajalike uuesti renderdamiste ennetamiseks
Kui olete tuvastanud komponendid, mis põhjustavad jõudlusprobleeme, saate kasutada erinevaid tehnikaid mittevajalike uuesti renderdamiste vältimiseks:
1. Memoiseerimine
Memoiseerimine on võimas optimeerimistehnika, mis hõlmab kulukate funktsioonikutsete tulemuste vahemällu salvestamist ja vahemällu salvestatud tulemuse tagastamist, kui samad sisendid uuesti esinevad. Reactis saab memoiseerimist kasutada komponentide uuesti renderdamise vältimiseks, kui nende omadused (props) pole muutunud.
a. React.memo
React.memo
on kõrgema järgu komponent, mis memoiseerib funktsionaalse komponendi. See võrdleb pinnapealselt praeguseid omadusi eelmistega ja renderdab komponendi uuesti ainult siis, kui omadused on muutunud.
Näide:
const MyComponent = React.memo(function MyComponent(props) {
return <div>{props.data}</div>;
});
Vaikimisi teostab React.memo
kõigi omaduste pinnapealse võrdluse. Võrdlusloogika kohandamiseks saate pakkuda kohandatud võrdlusfunktsiooni teise argumendina React.memo
-le.
const MyComponent = React.memo(function MyComponent(props) {
return <div>{props.data}</div>;
}, (prevProps, nextProps) => {
// Tagasta true, kui omadused on võrdsed, false, kui omadused on erinevad
return prevProps.data === nextProps.data;
});
b. useMemo
useMemo
on Reacti hook, mis memoiseerib arvutuse tulemuse. See võtab argumendiks funktsiooni ja sõltuvuste massiivi. Funktsioon käivitatakse uuesti ainult siis, kui mõni sõltuvus muutub, ja järgmistel renderdamistel tagastatakse memoiseeritud tulemus.
useMemo
on eriti kasulik kulukate arvutuste memoiseerimiseks või stabiilsete viidete loomiseks objektidele või funktsioonidele, mis edastatakse lastekomponentidele omadustena.
Näide:
const memoizedValue = useMemo(() => {
// Teosta siin kulukas arvutus
return computeExpensiveValue(a, b);
}, [a, b]);
2. PureComponent
PureComponent
on Reacti komponentide baasklass, mis rakendab oma shouldComponentUpdate
meetodis omaduste ja oleku pinnapealset võrdlust. Kui omadused ja olek pole muutunud, siis komponenti uuesti ei renderdata.
PureComponent
on hea valik komponentidele, mis sõltuvad renderdamisel ainult oma omadustest ja olekust ning ei tugine kontekstile ega muudele välistele teguritele.
Näide:
class MyComponent extends React.PureComponent {
render() {
return <div>{this.props.data}</div>;
}
}
Oluline märkus: PureComponent
ja React.memo
teostavad pinnapealseid võrdlusi. See tähendab, et nad võrdlevad ainult objektide ja massiivide viiteid, mitte nende sisu. Kui teie omadused või olek sisaldavad pesastatud objekte või massiive, peate võib-olla kasutama selliseid tehnikaid nagu muutumatus, et tagada muudatuste korrektne tuvastamine.
3. shouldComponentUpdate
ElutsĂĽkli meetod shouldComponentUpdate
võimaldab teil käsitsi kontrollida, kas komponent peaks uuesti renderdama. See meetod saab argumentidena järgmised omadused (next props) ja järgmise oleku (next state) ning peaks tagastama true
, kui komponent peaks uuesti renderdama, või false
, kui mitte.
Kuigi shouldComponentUpdate
annab kõige rohkem kontrolli uuesti renderdamise üle, nõuab see ka kõige rohkem käsitsitööd. Peate hoolikalt võrdlema asjakohaseid omadusi ja olekut, et määrata, kas uuesti renderdamine on vajalik.
Näide:
class MyComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// Võrdle siin omadusi ja olekut
return nextProps.data !== this.props.data || nextState.count !== this.state.count;
}
render() {
return <div>{this.props.data}</div>;
}
}
Hoiatus: shouldComponentUpdate
vale rakendamine võib põhjustada ootamatut käitumist ja vigu. Veenduge, et teie võrdlusloogika oleks põhjalik ja arvestaks kõiki asjakohaseid tegureid.
4. useCallback
useCallback
on Reacti hook, mis memoiseerib funktsiooni definitsiooni. See võtab argumendiks funktsiooni ja sõltuvuste massiivi. Funktsioon defineeritakse uuesti ainult siis, kui mõni sõltuvus muutub, ja järgmistel renderdamistel tagastatakse memoiseeritud funktsioon.
useCallback
on eriti kasulik funktsioonide edastamiseks omadustena lastekomponentidele, mis kasutavad React.memo
või PureComponent
. Funktsiooni memoiseerimisega saate vältida lastekomponendi mittevajalikku uuesti renderdamist, kui vanemkomponent uuesti renderdab.
Näide:
const handleClick = useCallback(() => {
// Käsitse kliki sündmust
console.log('Clicked!');
}, []);
5. Muutumatus (Immutability)
Muutumatus on programmeerimiskontseptsioon, mis hõlmab andmete käsitlemist muutumatutena, mis tähendab, et neid ei saa pärast loomist muuta. Muutumatute andmetega töötamisel loovad kõik muudatused uue andmestruktuuri, selle asemel et muuta olemasolevat.
Muutumatus on Reacti uuesti renderdamiste optimeerimisel ülioluline, sest see võimaldab Reactil pinnapealsete võrdluste abil kergesti tuvastada muudatusi omadustes ja olekus. Kui muudate objekti või massiivi otse, ei suuda React muutust tuvastada, sest viide objektile või massiivile jääb samaks.
Reactis muutumatute andmetega töötamiseks saate kasutada teeke nagu Immutable.js või Immer. Need teegid pakuvad andmestruktuure ja funktsioone, mis muudavad muutumatute andmete loomise ja nendega manipuleerimise lihtsamaks.
Näide Immeriga:
import { useImmer } from 'use-immer';
function MyComponent() {
const [data, setData] = useImmer({
name: 'John',
age: 30
});
const updateName = () => {
setData(draft => {
draft.name = 'Jane';
});
};
return (
<div>
<p>Nimi: {data.name}</p>
<button onClick={updateName}>Uuenda nime</button>
</div>
);
}
6. Koodi jaotamine ja laisk laadimine (Code Splitting and Lazy Loading)
Koodi jaotamine on tehnika, mis hõlmab teie rakenduse koodi jagamist väiksemateks osadeks, mida saab laadida vastavalt vajadusele. See võib oluliselt parandada teie rakenduse esialgset laadimisaega, kuna brauser peab alla laadima ainult selle koodi, mis on vajalik praeguse vaate jaoks.
React pakub sisseehitatud tuge koodi jaotamiseks, kasutades funktsiooni React.lazy
ja komponenti Suspense
. React.lazy
võimaldab teil komponente dünaamiliselt importida, samas kui Suspense
võimaldab teil kuvada varu-kasutajaliidest, kuni komponent laeb.
Näide:
import React, { Suspense } from 'react';
const MyComponent = React.lazy(() => import('./MyComponent'));
function App() {
return (
<Suspense fallback={<div>Laen...</div>}>
<MyComponent />
</Suspense>
);
}
7. Võtmete (Keys) tõhus kasutamine
Reactis elementide loendite renderdamisel on ülioluline anda igale elemendile unikaalne võti. Võtmed aitavad Reactil tuvastada, millised elemendid on muutunud, lisatud või eemaldatud, võimaldades tal DOM-i tõhusalt uuendada.
Vältige massiiviindeksite kasutamist võtmetena, kuna need võivad muutuda, kui elementide järjekord massiivis muutub, mis põhjustab mittevajalikke uuesti renderdamisi. Selle asemel kasutage iga elemendi jaoks unikaalset identifikaatorit, näiteks ID-d andmebaasist või genereeritud UUID-d.
8. Konteksti (Context) kasutamise optimeerimine
Reacti kontekst pakub viisi andmete jagamiseks komponentide vahel, ilma et peaks omadusi (props) selgesõnaliselt läbi iga komponendipuu taseme edasi andma. Kuid konteksti liigne kasutamine võib põhjustada jõudlusprobleeme, kuna iga konteksti tarbiv komponent renderdab uuesti iga kord, kui konteksti väärtus muutub.
Konteksti kasutamise optimeerimiseks kaaluge järgmisi strateegiaid:
- Kasutage mitut väiksemat konteksti: Selle asemel, et kasutada ühte suurt konteksti kogu rakenduse andmete salvestamiseks, jaotage see väiksemateks, konkreetsema fookusega kontekstideks. See vähendab nende komponentide arvu, mis uuesti renderdavad, kui konkreetne konteksti väärtus muutub.
- Memoiseerige konteksti väärtused: Kasutage
useMemo
-d, et memoiseerida väärtused, mida konteksti pakkuja pakub. See hoiab ära konteksti tarbijate mittevajalikud uuesti renderdamised, kui väärtused pole tegelikult muutunud. - Kaaluge alternatiive kontekstile: Mõnel juhul võivad muud olekuhalduslahendused, nagu Redux või Zustand, olla kontekstist sobivamad, eriti keeruliste rakenduste puhul, kus on suur hulk komponente ja sagedased olekuvärskendused.
Rahvusvahelised kaalutlused
Reacti rakenduste optimeerimisel globaalsele publikule on oluline arvestada järgmiste teguritega:
- Erinevad võrgukiirused: Erinevates piirkondades olevatel kasutajatel võivad olla väga erinevad võrgukiirused. Optimeerige oma rakendus, et minimeerida võrgu kaudu allalaaditavate ja edastatavate andmete hulka. Kaaluge selliste tehnikate kasutamist nagu piltide optimeerimine, koodi jaotamine ja laisk laadimine.
- Seadmete võimekus: Kasutajad võivad teie rakendusele juurde pääseda erinevate seadmetega, alates tipptasemel nutitelefonidest kuni vanemate ja vähem võimsate seadmeteni. Optimeerige oma rakendus, et see toimiks hästi erinevatel seadmetel. Kaaluge selliste tehnikate kasutamist nagu reageeriv disain, kohanduvad pildid ja jõudluse profiilimine.
- Lokaliseerimine: Kui teie rakendus on lokaliseeritud mitme keele jaoks, veenduge, et lokaliseerimisprotsess ei tekitaks jõudluse kitsaskohti. Kasutage tõhusaid lokaliseerimisteeke ja vältige tekstistringide otse oma komponentidesse kirjutamist.
Reaalse elu näited
Vaatleme mõningaid reaalse elu näiteid, kuidas neid optimeerimistehnikaid rakendada saab:
1. E-poe tootekataloog
Kujutage ette e-poe veebisaiti, millel on tootekataloogi leht, kus kuvatakse sadu tooteid. Iga tooteartikkel renderdatakse eraldi komponendina.
Ilma optimeerimiseta renderdaksid kõik tootekompnendid uuesti iga kord, kui kasutaja tootenimekirja filtreerib või sorteerib, mis põhjustab aeglase ja katkendliku kogemuse. Selle optimeerimiseks võiksite kasutada React.memo
tootekompnentide memoiseerimiseks, tagades, et need renderdavad uuesti ainult siis, kui nende omadused (nt toote nimi, hind, pilt) muutuvad.
2. Sotsiaalmeedia voog
Sotsiaalmeedia voog kuvab tavaliselt postituste loendi, millest igaühel on kommentaarid, meeldimised ja muud interaktiivsed elemendid. Kogu voo uuesti renderdamine iga kord, kui kasutaja postitust meeldib või kommentaari lisab, oleks ebaefektiivne.
Selle optimeerimiseks võiksite kasutada useCallback
postituste meeldimise ja kommenteerimise sündmuste käsitlejate memoiseerimiseks. See hoiaks ära postituse komponentide mittevajaliku uuesti renderdamise, kui need sündmuste käsitlejad käivitatakse.
3. Andmete visualiseerimise armatuurlaud
Andmete visualiseerimise armatuurlaud kuvab sageli keerulisi diagramme ja graafikuid, mida uuendatakse sageli uute andmetega. Nende diagrammide uuesti renderdamine iga kord, kui andmed muutuvad, võib olla arvutuslikult kulukas.
Selle optimeerimiseks võiksite kasutada useMemo
diagrammi andmete memoiseerimiseks ja renderdada diagramme uuesti ainult siis, kui memoiseeritud andmed muutuvad. See vähendaks oluliselt uuesti renderdamiste arvu ja parandaks armatuurlaua üldist jõudlust.
Parimad praktikad
Siin on mõned parimad praktikad, mida Reacti uuesti renderdamiste optimeerimisel meeles pidada:
- Profiilige oma rakendust: Kasutage Reacti profiilijat või "Why Did You Render?", et tuvastada komponente, mis põhjustavad jõudlusprobleeme.
- Alustage lihtsamatest ülesannetest: Keskenduge nende komponentide optimeerimisele, mis renderdavad kõige sagedamini uuesti või mille renderdamine võtab kõige kauem aega.
- Kasutage memoiseerimist mõistlikult: Ärge memoiseerige iga komponenti, kuna memoiseerimisel endal on oma kulu. Memoiseerige ainult komponente, mis tegelikult jõudlusprobleeme põhjustavad.
- Kasutage muutumatust: Kasutage muutumatuid andmestruktuure, et Reactil oleks lihtsam tuvastada muudatusi omadustes ja olekus.
- Hoidke komponendid väikesed ja fokusseeritud: Väiksemaid ja konkreetsema fookusega komponente on lihtsam optimeerida ja hooldada.
- Testige oma optimeerimisi: Pärast optimeerimistehnikate rakendamist testige oma rakendust põhjalikult, et veenduda, et optimeerimistel on soovitud mõju ja need pole tekitanud uusi vigu.
Kokkuvõte
Mittevajalike uuesti renderdamiste ennetamine on Reacti rakenduste jõudluse optimeerimisel ülioluline. Mõistes, kuidas Reacti renderdamisprotsess toimib, ja kasutades selles juhendis kirjeldatud tehnikaid, saate oluliselt parandada oma rakenduste reageerimisvõimet ja tõhusust, pakkudes paremat kasutajakogemust kasutajatele üle kogu maailma. Ärge unustage oma rakendust profiilida, tuvastada jõudlusprobleeme põhjustavad komponendid ja rakendada nende probleemide lahendamiseks sobivaid optimeerimistehnikaid. Järgides neid parimaid praktikaid, saate tagada, et teie Reacti rakendused on kiired, tõhusad ja skaleeritavad, sõltumata teie koodibaasi keerukusest või suurusest.