Alkuperäisen käyttöönotonsa jälkeen React on muuttanut käyttöliittymäkehittäjien ajattelutapaa verkkosovelluksia rakennettaessa. Virtual DOM: n avulla React tekee käyttöliittymän (käyttöliittymän) päivityksistä yhtä tehokkaita kuin koskaan, samalla kun web-sovelluksesi on tarkempi. Mutta miksi hyvin kokoiset React-verkkosovellukset toimivat edelleen huonosti?
No, avain on miten käytät Reactia.
Moderni etupään kirjasto, kuten Reagoi se ei tee maagisesti sovellustasi nopeammaksi. Kehittäjän on ymmärrettävä, miten React toimii ja miten komponentit elävät komponenttien elinkaaren eri vaiheissa.
Reactin avulla voit saada monia sen tarjoamista parannuksista mittaamalla ja optimoimalla, kuinka ja milloin komponenttisi palaavat. React tarjoaa vain tarvittavat työkalut ja toiminnot tämän helpottamiseksi.
Tässä React-opetusohjelmassa opit, kuinka voit mitata React-komponenttien suorituskykyä ja optimoida ne tehokkaamman ja tehokkaamman React-verkkosovelluksen rakentamiseksi. Samoin opit, kuinka muutama JavaScript-käytäntö auttaa myös React-verkkosovellustasi saumattomassa käyttökokemuksessa.
Ennen kuin ryhdymme optimointitekniikoihin, meidän on ymmärrettävä paremmin Reactin toiminta.
Reactin ytimessä on JSX-syntakse ja Reactin kyky rakentaa ja vertailla. Virtuaalinen DOM . Perustamisestaan lähtien React on vaikuttanut moniin muihin etupään kirjastoihin. Kirjastot, kuten Vue.js, tukeutuvat myös virtuaalisten DOM: ien ideaan.
React toimii seuraavasti:
Jokainen React-sovellus alkaa juurikomponentilla ja koostuu monista puumuodostuksen komponenteista. Reactin komponentit ovat 'toimintoja', jotka poistuvat käyttöliittymästä saamiensa tietojen (tuen ja tilan) perusteella.
Voimme symboloida tätä nimellä F
.
UI = F(data)
Käyttäjät ovat vuorovaikutuksessa käyttöliittymän kanssa ja aiheuttavat muutoksen tiedoissa. Olipa vuorovaikutus painikkeen napsauttaminen, kuvan koskettaminen, kohteiden vetäminen luettelosta, AJAX-pyynnöt, jotka kutsuvat sovellusliittymiä, jne., Kaikki nämä vuorovaikutukset muuttavat vain tietoja. Ne eivät koskaan saa käyttöliittymää muuttumaan suoraan.
Tässä data on kaikki, mikä määrittää verkkosovelluksen tilan, eikä vain sitä, mitä olet tallentanut tietokantaan. Jopa etupään tilojen palat (esim. Mikä ikkuna on valittu tällä hetkellä tai onko ruutu valittu tällä hetkellä) ovat osa näitä tietoja.
Kun näissä tiedoissa tapahtuu muutoksia, React käyttää komponenttitoimintoja poistuakseen käyttöliittymästä, mutta vain käytännössä:
UI1 = F(data1) UI2 = F(data2)
React laskee nykyisen käyttöliittymän ja uuden käyttöliittymän väliset erot soveltamalla vertailualgoritmia virtuaalisen DOM: n kahteen versioon.
Changes = Diff(UI1, UI2)
React jatkaa tämän jälkeen vain muutoksia selaimen todelliseen käyttöliittymään.
Kun komponenttiin liittyvät tiedot muuttuvat, React määrittää, tarvitaanko DOM-päivitystä todella. Tämä antaa Reactille mahdollisuuden välttää kalliita DOM-manipulaatiotoimintoja selaimessa, kuten DOM-solmujen luominen ja pääsy joihinkin olemassa oleviin enemmän kuin tarpeen.
Tämä toistuva erilaistumislaskenta ja komponenttien jättäminen voivat olla yksi Reactin suorituskykyongelmien ensisijaisista lähteistä missä tahansa React-sovelluksessa. React-sovelluksen rakentaminen, jossa algoritmien eriyttämistä ei voida tehokkaasti sovittaa yhteen, mikä aiheuttaa koko sovelluksen toistuvan pudottamisen, voi johtaa turhauttavaan ja aikaa vievään kokemukseen.
Mutta mitä optimoimme tarkalleen?
No, alkuvaiheessa jättämisen jälkeen React rakentaa DOM-puun näin:
Koska osa tiedoista muuttuu, haluamme Reactin tekemän pudottamaan takaisin vain komponentit, joihin muutos vaikuttaa suoraan (ja mahdollisesti ohittaa diff-prosessin muille komponenteille):
React päätyy kuitenkin tekemään:
Yllä olevassa kuvassa kaikki keltaiset solmut renderoidaan ja erotellaan (diff), mikä johtaa ajan / resurssien tuhlaamiseen. Tähän me panemme optimointipyrkimyksemme pääasiassa. Kunkin komponentin asettaminen vain renderöimiseksi (diff) tarvittaessa tarvittaessa voimme palauttaa nämä menetetyt suorittimen jaksot.
React-kirjaston kehittäjät ottivat tämän huomioon ja antoivat meille koukun, jotta voimme tehdä juuri sen: toiminto, jonka avulla voimme kertoa Reactille, kun komponentin renderointi on ohitettava.
Kuten Rob Pike sen sävyisesti sanoo aikataulutussäännöt :
Koon mukaan. Älä säädä nopeutta, ennen kuin olet mitannut, ja silloinkin älä, ellei yksi koodin osa varjele loput.
Älä optimoi koodia, jonka uskot hidastavan sovellustasi. Sen sijaan anna Reactin suorituskyvyn mittaustyökalujen ohjata sinua matkan varrella.
Reactilla on a vahva työkalu tätä varten. Kun käytetään react-addons-perf
saat yhteenvedon sovelluksesi yleisestä suorituskyvystä.
Käyttö on hyvin yksinkertaista:
Import Perf from 'react-addons-perf' Perf.start(); // use the app Perf.stop(); Perf.printWasted();
Tämä tulostaa taulukon, jossa näkyy komponenttien menetetty aika renderoinnissa.
Kirjasto tarjoaa muita toimintoja, joiden avulla voit tulostaa hukkaan menneen ajan eri näkökohdat erikseen (esim. printInclusive()
Tai printExclusive()
-toimintojen avulla) tai jopa tulostaa DOM-käsittelytoimintoja (käyttämällä printOperations()
) .
Jos olet visuaalinen henkilö sitten react-perf-tool
on juuri sitä mitä tarvitset.
react-perf-tool
Se perustuu react-addons-perf
-kirjastoon. Se antaa sinulle visuaalisen tavan selvittää sovelluksesi suorituskyky React-sovelluksella. Se käyttää alla olevaa kirjastoa mittausten saamiseen ja näyttää ne sitten kaavioina.
Hyvin usein tämä on paljon helpompi tapa huomata palkit. Voit käyttää sitä helposti lisäämällä sen komponenttina sovellukseesi.
React suorittaa oletusarvoisesti, renderöi virtuaalisen DOM: n ja vertaa kunkin puun komponentin eroa niiden muutoksissa niiden rekvisiitassa ja tilassa. Mutta se ei tietenkään ole järkevää.
Kun sovelluksesi kasvaa, koko virtuaalisen verkkotunnuksen renderointi ja vertailu jokaisessa toiminnossa lopulta hidastuu.
React tarjoaa kehittäjälle yksinkertaisen tavan ilmoittaa, onko komponentti renderöitävä uudelleen. Täällä shouldComponentUpdate
tulee peliin.
function shouldComponentUpdate(nextProps, nextState) { return true; }
Kun tämä funktio palaa tosi mille tahansa komponentille, se sallii renderoinnin erotteluprosessin.
Tämä antaa sinulle helpon tavan hallita renderoinnin erilaistamisprosessia. Kun haluat estää komponentin täydellisen renderoinnin, se on yksinkertaisesti tulos falso
toiminnon. Funktion sisällä voit verrata tukijoukkoa ja nykyistä tilaa sekä seuraavia selvittääksesi, onko uudelleenhahmontaminen tarpeen:
function shouldComponentUpdate(nextProps, nextState) { return nextProps.id !== this.props.id; }
Jotta tämä optimointitekniikka olisi hieman helpompaa ja automatisoitua, React tarjoaa niin kutsutun 'puhtaan' komponentin. A React.PureComponent
on täsmälleen kuin React.Component
joka toteuttaa toiminnon shouldComponentUpdate()
tyhjällä tuen ja tilan vertailulla.
A React.PureComponent
vastaa suunnilleen tätä:
class MyComponent extends React.Component { shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this.props, nextProps) && shallowCompare(this.state, nextState); } … }
Koska vertailu on tyhjä, saatat löytää siitä hyödyllisen vain, kun:
forceUpdate()
päivittääksesi komponentin.Entä jos voisit käyttää React.PureComponent
ja sinulla on edelleen tehokas tapa nähdä, milloin tuki tai monimutkainen tila on muuttunut automaattisesti? Tässä muuttumattomat tietorakenteet helpottavat elämäämme.
Ajatus muuttumattomien tietorakenteiden käytöstä on yksinkertainen. Kun monimutkaisia tietoja sisältävä objekti muuttuu, objektin muutosten tekemisen sijaan se luo kopion kyseisestä objektista muutosten kanssa. Tämä tekee tietojen muutosten havaitsemisen yhtä yksinkertaiseksi kuin kahden objektin viitteiden vertaaminen.
Voit käyttää Object.assign
tai _.extend
(sivulta Underscore.js tai Lodash):
const newValue2 = Object.assign({}, oldValue); const newValue2 = _.extend({}, oldValue);
Vielä parempi, voit käyttää kirjastoa, joka tarjoaa muuttumattomia tietorakenteita:
var map1 = Immutable.Map({a:1, b:2, c:3}); var map2 = map1.set('b', 2); assert(map1.equals(map2) === true); var map3 = map1.set('b', 50); assert(map1.equals(map3) === false);
Täällä, Immutable.Map
tarjoaa kirjasto Immutable.js .
Aina kun kartta päivitetään set
-menetelmällään, uusi kartta palautetaan vain, jos asetettu toiminto muutti taustalla olevaa arvoa. Muussa tapauksessa sama kartta palautetaan.
Voit oppia lisää muuttumattomien tietorakenteiden käytöstä tässä .
Kun kehität sovellusta Reactin kanssa, saat erittäin hyödyllisiä varoituksia ja virheilmoituksia. Nämä tekevät virheiden ja ongelmien tunnistamisen kehityksen aikana erittäin helpoksi. Mutta ne maksavat myös osan esityksestä.
Jos tarkastelet React-lähdekoodia, näet paljon if (process.env.NODE_ENV != 'production')
-merkkejä. Nämä Reactin kehitysympäristössä käyttämät koodinpalat eivät ole käyttäjän tarvitsemia. Tuotantoympäristöissä kaikki tämä tarpeeton koodi voidaan hylätä.
Jos työnsit projektiasi create-react-app
: lla, voit suorittaa npm run build
tuottaa tuotantorakenne ilman tätä ylimääräistä koodia. Jos käytät suoraan Webpackia, voit suorittaa webpack -p
(mikä vastaa webpack --optimize-minimize --define process.env.NODE_ENV=''production''
.
On hyvin yleistä nähdä funktiot sidottuina komponentin kontekstiin renderoidussa funktiossa. Näin on usein, kun käytämme näitä toimintoja varhaisen vaiheen komponenttitapahtumien käsittelemiseen.
// Creates a new `handleUpload` function during each render() // ...as do inlined arrow functions this.handleUpload(files)} />
Tämä aiheuttaa render()
luo uusi toiminto kuhunkin renderöintiin. Parempi tapa tehdä sama on:
class App extends React.Component { constructor(props) { super(props); this.handleUpload = this.handleUpload.bind(this); } render() { … … } }
Yhden sivun React-verkkosovelluksissa niputetaan yleensä kaikki käyttöliittymämme JavaScript-koodit yhteen pienennettyyn tiedostoon. Tämä toimii hyvin keskikokoisissa verkkosovelluksissa. Mutta kun sovellus alkaa kasvaa, tämän JavaScript-tiedoston toimittaminen selaimeen sellaisenaan voi olla hyvin aikaa vievä prosessi.
Jos käytät Webpackia sovelluksesi rakentamiseen, voit parantaa koodiasi erottamalla sen kyvyt erottaa rakennettu sovelluskoodi myös useiksi paloiksi ja toimittaa ne selaimeen tarvittavina aikoina.
Erottelua on kahta tyyppiä: resurssien erottelu ja on-demand-koodien erotus.
Resurssien erottelun avulla voit erottaa resurssin sisällön useiksi tiedostoiksi. Esimerkiksi CommonsChunkPlugin-sovelluksen avulla voit purkaa yleisen koodin (kuten kaikki ulkoiset kirjastot) oikeaan palatiedostoon. Käyttämällä ExtractTextWebpackPlugin-sovellusta voit purkaa kaikki CSS-koodit erilliseen CSS-tiedostoon.
Tämän tyyppinen erottaminen auttaa sinua kahdella tavalla. Se auttaa hakukonetta tallentamaan harvemmin vaihtuvat resurssit. Se auttaa myös hakijaa hyödyntämään rinnakkaislatausta latausaikojen lyhentämiseksi.
Webpackin merkittävin piirre on koodin erottaminen pyynnöstä. Tämä voi pitää alkuperäisen latauksen pienenä vähentämällä sovelluksen lataamiseen kuluvaa aikaa. Selain voi siis ladata koodipaloja pyynnöstä, kun sovellus sitä tarvitsee.
Voit oppia lisää Webpack-koodien erottamisesta tässä .
React-sovelluksen JS-tiedostoryhmä on yleensä erittäin suuri, joten verkkosivun latautumisen nopeuttamiseksi voimme ottaa Gzipin käyttöön verkkopalvelimessa (Apache, Nginx jne.)
Kaikki modernit hakukoneet tukevat ja neuvottelevat automaattisesti Gzip-pakkauksen HTTP-pyynnöille. Gzip-pakkauksen ottaminen käyttöön voi vähentää siirretyn vastauksen kokoa 90%, mikä voi vähentää resurssin latausaikaa, vähentää asiakkaan datan käyttöä ja parantaa sivujen renderointiaikaa.
Tarkista verkkopalvelimen ohjeista, miten pakkaus otetaan käyttöön:
Käytä ESLintiä melkein kaikissa JavaScript-projekteissa. Reagoi ei ole ero.
Kanssa eslint-plugin-react
, pakotat itsesi sopeutumaan moniin Reactin ohjelmointisääntöihin, mikä voi hyödyttää koodiasi pitkällä aikavälillä ja välttää monia yleisiä ongelmia ja haittoja, jotka johtuvat huonosta koodin kirjoittamisesta.
Saadaksesi kaiken irti Reactista, sinun on hyödynnettävä sen työkaluja ja tekniikoita. React-verkkosovelluksen suorituskyky on sen komponenttien yksinkertaisuudessa. Ylivoimainen erottelu- ja renderointialgoritmi voi saada sovelluksesi toimimaan huonosti hyvin turhauttavalla tavalla.
Ennen kuin voit optimoida sovelluksesi, sinun on ymmärrettävä, kuinka React-komponentit toimivat ja miten ne renderoidaan selaimessasi. Reactin elinkaarimenetelmät antavat sinulle tapoja estää komponenttiasi renderoimasta tarpeettomasti. Poista nämä esteet ja saat sovelluksesi suorituskyvyn, jonka käyttäjät ansaitsevat.
Vaikka on olemassa useita tapoja optimoida verkkosovellus Reactin avulla, komponenttien puhdistaminen päivitettäväksi vain tarvittaessa estää suorituskyvyn parantamisen.
Kuinka mitataan ja optimoidaan verkkosovelluksesi suorituskykyä Reactin avulla? Jaa se alla olevissa kommenteissa.