React
Prestanda
Sök…
Grunderna - HTML DOM vs Virtual DOM
HTML DOM är dyrt
Varje webbsida representeras internt som ett träd av objekt. Denna representation kallas Document Object Model . Dessutom är det ett språkneutralt gränssnitt som gör att programmeringsspråk (som JavaScript) får åtkomst till HTML-elementen.
Med andra ord
HTML DOM är en standard för att få, ändra, lägga till eller ta bort HTML-element.
DOM-verksamheten är dock extremt dyr .
Virtual DOM är en lösning
Så Reacts team kom med idén att abstrahera HTML DOM och skapa sin egen virtuella DOM för att beräkna det minsta antalet operationer som vi behöver använda på HTML DOM för att replikera det aktuella tillståndet för vår applikation.
Den virtuella DOM sparar tid från onödiga DOM-ändringar.
Hur exakt?
Vid varje tidpunkt har React programtillståndet representerat som en Virtual DOM
. När programtillståndet ändras är det dessa steg som React utför för att optimera prestanda
Generera en ny virtuell DOM som representerar det nya tillståndet i vår applikation
Jämför den gamla Virtual DOM (som representerar den nuvarande HTML DOM) mot den nya Virtual DOM
Baserat på 2. hitta det minsta antalet operationer för att förvandla den gamla Virtual DOM (som representerar den aktuella HTML DOM) till den nya Virtual DOM
- för att lära sig mer om det - läs React's Diff Algoritm
- När dessa operationer har hittats, mappas de till deras motsvarande HTML DOM- operationer
- kom ihåg att Virtual DOM endast är en abstraktion av HTML DOM och det finns en isomorf relation mellan dem
- Nu tillämpas nu det minsta antalet operationer som har hittats och överförts till motsvarande HTML DOM- operationer direkt på applikationens HTML DOM , vilket sparar tid från att modifiera HTML DOM onödigt.
Obs! Operationer som tillämpas på Virtual DOM är billiga eftersom Virtual DOM är ett JavaScript-objekt.
Reacts diff-algoritm
Generering av det minsta antalet operationer för att förvandla ett träd till ett annat har en komplexitet i storleksordningen O (n ^ 3) där n är antalet noder i trädet. React förlitar sig på två antaganden för att lösa detta problem på en linjär tid - O (n)
Två komponenter i samma klass kommer att generera liknande träd och två komponenter i olika klasser genererar olika träd.
Det är möjligt att tillhandahålla en unik nyckel för element som är stabila på olika sätt.
För att avgöra om två noder är olika skiljer React 3 fall
- Två noder är olika om de har olika typer.
- till exempel
<div>...</div>
skiljer sig från<span>...</span>
- När två noder har olika nycklar
- till exempel
<div key="1">...</div>
skiljer sig från<div key="2">...</div>
Det följande är dessutom avgörande och oerhört viktigt att förstå om du vill optimera prestanda
Om de [två noder] inte är av samma typ kommer React inte ens att försöka matcha vad de gör. Det kommer bara att ta bort den första från DOM och sätta in den andra.
Här är varför
Det är mycket osannolikt att ett element kommer att generera en DOM som kommer att se ut som en skulle generera. Istället för att spendera tid på att försöka matcha dessa två strukturer, bygger React bara trädet från grunden.
tips och tricks
När två noder inte är av samma typ försöker React inte matcha dem - det tar bara bort den första noden från DOM och infogar den andra. Det är därför det första tipset säger
- Om du ser dig själv växla mellan två komponentklasser med mycket likartad utgång, kanske du vill göra det till samma klass.
- Använd shouldComponentUpdate för att förhindra att komponenten återförs, om du vet att den inte kommer att ändras, till exempel
shouldComponentUpdate: function(nextProps, nextState) {
return nextProps.id !== this.props.id;
}
Prestandamätning med ReactJS
Du kan inte förbättra något du inte kan mäta . För att förbättra React-komponenternas prestanda bör du kunna mäta den. ReactJS har tilläggsverktyg för att mäta prestanda. Importera modulen react-addons-perf
att mäta prestanda
import Perf from 'react-addons-perf' // ES6 var Perf = require('react-addons-perf') // ES5 with npm var Perf = React.addons.Perf; // ES5 with react-with-addons.js
Du kan använda metoder nedan från den importerade Perf
modulen:
- Perf.printInclusive ()
- Perf.printExclusive ()
- Perf.printWasted ()
- Perf.printOperations ()
- Perf.printDOM ()
Den viktigaste som du kommer att behöva mest av tiden är Perf.printWasted()
som ger dig en tabellrepresentation av din enskilda komponents bortkastade tid
Du kan notera kolumnen Avfallad tid i tabellen och förbättra komponentens prestanda med hjälp av avsnittet Tips & tricks ovan
Se React Official Guide och utmärkt artikel av Benchling Engg. om React Performance