Leer hoe u Chrome en DevTools kunt gebruiken om geheugenproblemen op te sporen die de prestaties van de pagina beïnvloeden, waaronder geheugenlekken, geheugenophoping en frequente ophaalacties.
Samenvatting
- Ontdek hoeveel geheugen uw pagina gebruikt met Chrome Taakbeheer.
- Visualiseer het geheugengebruik in de loop van de tijd met tijdlijnopnamen.
- Identificeer losstaande DOM-bomen (een veelvoorkomende oorzaak van geheugenlekken) met Heap Snapshots.
- Ontdek wanneer er nieuw geheugen wordt toegewezen in uw JS-heap met toewijzingstijdlijnopnamen.
- Identificeer losstaande elementen die worden behouden door JavaScript-referentie.
Overzicht
In de geest van het RAIL- prestatiemodel moet de focus van uw prestatie-inspanningen liggen op uw gebruikers.
Geheugenproblemen zijn belangrijk omdat ze vaak waarneembaar zijn voor gebruikers. Gebruikers kunnen geheugenproblemen op de volgende manieren waarnemen:
- De prestaties van een pagina worden in de loop van de tijd steeds slechter. Dit is mogelijk een symptoom van een geheugenlek. Er is sprake van een geheugenlek als een bug op de pagina ervoor zorgt dat de pagina in de loop van de tijd steeds meer geheugen gaat gebruiken.
- De prestaties van een pagina zijn voortdurend slecht. Dit is mogelijk een symptoom van een opgeblazen geheugen. Er is sprake van geheugenophoping wanneer een pagina meer geheugen gebruikt dan nodig is voor een optimale paginasnelheid.
- De prestaties van een pagina zijn vertraagd of lijken regelmatig te pauzeren. Dit is mogelijk een symptoom van frequente afvalinzameling. Garbage collection is wanneer de browser geheugen terugwint. De browser bepaalt wanneer dit gebeurt. Tijdens verzamelingen wordt alle uitvoering van scripts onderbroken. Dus als de browser veel afval verzamelt, zal de uitvoering van het script vaak worden gepauzeerd.
Geheugenopgeblazen gevoel: hoeveel is "te veel"?
Een geheugenlek is eenvoudig te definiëren. Als een site steeds meer geheugen gebruikt, is er sprake van een lek. Maar geheugenzwelling is iets moeilijker vast te stellen. Wat kwalificeert als "te veel geheugen gebruiken"?
Hier zijn geen harde cijfers voor, omdat verschillende apparaten en browsers verschillende mogelijkheden hebben. Dezelfde pagina die soepel draait op een high-end smartphone kan crashen op een low-end smartphone.
De sleutel hier is om het RAIL-model te gebruiken en u te concentreren op uw gebruikers. Ontdek welke apparaten populair zijn bij uw gebruikers en test vervolgens uw pagina op die apparaten. Als de ervaring voortdurend slecht is, overschrijdt de pagina mogelijk de geheugencapaciteit van die apparaten.
Houd het geheugengebruik in realtime in de gaten met Chrome Task Manager
Gebruik Chrome Task Manager als startpunt voor uw onderzoek naar geheugenproblemen. Taakbeheer is een realtime monitor die u vertelt hoeveel geheugen een pagina gebruikt.
Druk op Shift+Esc of ga naar het Chrome-hoofdmenu en selecteer Meer tools > Taakbeheer om Taakbeheer te openen.
Klik met de rechtermuisknop op de tabelkop van Taakbeheer en schakel JavaScript-geheugen in.
Deze twee kolommen vertellen u verschillende dingen over hoe uw pagina geheugen gebruikt:
- De kolom Geheugenvoetafdruk vertegenwoordigt het besturingssysteemgeheugen. DOM-knooppunten worden opgeslagen in het besturingssysteemgeheugen. Als deze waarde toeneemt, worden er DOM-knooppunten gemaakt.
De JavaScript-geheugenkolom vertegenwoordigt de JS-heap. Deze kolom bevat twee waarden. De waarde waarin u geïnteresseerd bent, is het live-nummer (het nummer tussen haakjes). Het live-nummer geeft aan hoeveel geheugen de bereikbare objecten op uw pagina gebruiken. Als dit aantal toeneemt, worden er nieuwe objecten gemaakt of groeien de bestaande objecten.
Visualiseer geheugenlekken met prestatie-opnames
U kunt het Prestatiepaneel ook als extra startpunt in uw onderzoek gebruiken. Met het paneel Prestaties kunt u het geheugengebruik van een pagina in de loop van de tijd visualiseren.
- Open het prestatiepaneel in DevTools.
- Schakel het selectievakje Geheugen in.
- Maak een opname .
Overweeg de volgende code om prestatiegeheugenopnamen te demonstreren:
var x = [];
function grow() {
for (var i = 0; i < 10000; i++) {
document.body.appendChild(document.createElement('div'));
}
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
Elke keer dat de knop waarnaar in de code wordt verwezen wordt ingedrukt, worden tienduizend div
knooppunten aan de documenttekst toegevoegd en wordt een reeks van een miljoen x
tekens op de x
array geduwd. Het uitvoeren van deze code levert een tijdlijnopname op zoals in de volgende schermafbeelding:
Eerst een uitleg van de gebruikersinterface. De HEAP- grafiek in het overzichtsvenster (onder NET ) vertegenwoordigt de JS-heap. Onder het overzichtsvenster bevindt zich het tellervenster . Hier ziet u het geheugengebruik uitgesplitst naar JS-heap (hetzelfde als de HEAP- grafiek in het overzichtspaneel ), documenten, DOM-knooppunten, luisteraars en GPU-geheugen. Als u een selectievakje uitschakelt, wordt het verborgen in de grafiek.
Nu een analyse van de code vergeleken met de schermafbeelding. Als je naar de knooppuntenteller (de groene grafiek) kijkt, kun je zien dat deze netjes overeenkomt met de code. Het aantal knooppunten neemt in discrete stappen toe. Je kunt ervan uitgaan dat elke toename van het aantal knooppunten een aanroep is voor grow()
. De JS-heapgrafiek (de blauwe grafiek) is niet zo eenvoudig. In overeenstemming met de beste praktijken is de eerste dip eigenlijk een gedwongen afvalophaling (behaald door op de knop afval verzamelen te drukken). Naarmate de opname vordert, kun je zien dat de JS-heapgrootte toeneemt. Dit is natuurlijk en te verwachten: de JavaScript-code creëert de DOM-knooppunten bij elke klik op een knop en doet veel werk wanneer het de reeks van een miljoen tekens creëert. Het belangrijkste hier is het feit dat de JS-heap hoger eindigt dan hij begon (het "begin" is hier het punt na de gedwongen afvalinzameling). Als je dit patroon van toenemende JS-heapgrootte of knooppuntgrootte in de echte wereld zou zien, zou dit mogelijk een geheugenlek betekenen.
Ontdek losstaande DOM-boomgeheugenlekken met Heap Snapshots
Een DOM-knooppunt kan alleen worden verzameld als er geen verwijzingen naar zijn vanuit de DOM-boom van de pagina of vanuit JavaScript-code. Er wordt gezegd dat een knooppunt "losgekoppeld" is wanneer het uit de DOM-structuur wordt verwijderd, maar sommige JavaScripts verwijzen er nog steeds naar. Losstaande DOM-knooppunten zijn een veelvoorkomende oorzaak van geheugenlekken. In deze sectie leert u hoe u de heap profilers van DevTools kunt gebruiken om losgemaakte knooppunten te identificeren.
Hier is een eenvoudig voorbeeld van vrijstaande DOM-knooppunten.
var detachedTree;
function create() {
var ul = document.createElement('ul');
for (var i = 0; i < 10; i++) {
var li = document.createElement('li');
ul.appendChild(li);
}
detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);
Als u op de knop klikt waarnaar in de code wordt verwezen, wordt een ul
knooppunt met tien li
kinderen gemaakt. Naar deze knooppunten wordt in de code verwezen, maar ze bestaan niet in de DOM-structuur, dus ze zijn losgekoppeld.
Heap-snapshots zijn een manier om losgemaakte knooppunten te identificeren. Zoals de naam al aangeeft, laten heap-snapshots zien hoe het geheugen is verdeeld over de JS-objecten en DOM-knooppunten van uw pagina op het tijdstip van de momentopname.
Om een momentopname te maken, opent u DevTools en gaat u naar het paneel Geheugen , selecteert u het keuzerondje Heap Snapshot en drukt u vervolgens op de knop Momentopname maken .
Het verwerken en laden van de momentopname kan enige tijd duren. Zodra het klaar is, selecteert u het in het linkerpaneel (genaamd Heap snapshots ).
Typ Detached
in het invoervak Klassefilter om te zoeken naar vrijstaande DOM-bomen.
Vouw de karaat uit om een vrijstaande boom te onderzoeken.
Klik op een knooppunt om het verder te onderzoeken. In het deelvenster Objecten ziet u meer informatie over de code die ernaar verwijst. In de volgende schermafbeelding ziet u bijvoorbeeld dat de variabele detachedTree
verwijst naar het knooppunt. Om dit specifieke geheugenlek te verhelpen, zou je de code die detachedTree
gebruikt, moeten bestuderen en ervoor zorgen dat de verwijzing naar het knooppunt wordt verwijderd wanneer deze niet langer nodig is.
Identificeer JS-heapgeheugenlekken met toewijzingstijdlijnen
De Allocation Timeline is een ander hulpmiddel dat u kan helpen geheugenlekken in uw JS-heap op te sporen.
Om de toewijzingstijdlijn te demonstreren, gebruikt u de volgende code:
var x = [];
function grow() {
x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
Elke keer dat de knop waarnaar in de code wordt verwezen, wordt ingedrukt, wordt een reeks van een miljoen tekens aan de x
array toegevoegd.
Om een toewijzingstijdlijn op te nemen, opent u DevTools, gaat u naar het paneel Geheugen , selecteert u het keuzerondje Toewijzingen op de tijdlijn , drukt u op de
knop Opnemen , voert u de actie uit waarvan u vermoedt dat deze het geheugenlek veroorzaakt en drukt u vervolgens op de knop Stop de opnameknop als je klaar bent.Let tijdens het opnemen op of er blauwe balken verschijnen op de toewijzingstijdlijn , zoals in de volgende schermafbeelding.
Die blauwe balken vertegenwoordigen nieuwe geheugentoewijzingen. Deze nieuwe geheugentoewijzingen zijn uw kandidaten voor geheugenlekken. U kunt op een balk inzoomen om het Constructor- venster zo te filteren dat alleen objecten worden weergegeven die tijdens het opgegeven tijdsbestek zijn toegewezen.
Vouw het object uit en klik op de waarde ervan om meer details erover te bekijken in het objectvenster . In de onderstaande schermafbeelding kunt u bijvoorbeeld, door de details te bekijken van het object dat nieuw is toegewezen, zien dat het is toegewezen aan de x
variabele in het Window
.
Onderzoek geheugentoewijzing per functie
Gebruik het toewijzingsbemonsteringsprofieltype in het paneel Geheugen om de geheugentoewijzing via de JavaScript-functie te bekijken.
- Selecteer het keuzerondje Toewijzingsbemonstering . Als er een medewerker op de pagina staat, kunt u die als profileringsdoel selecteren in het venster JavaScript VM-instantie selecteren .
- Druk op de Start- knop.
- Voer de acties uit op de pagina die u wilt onderzoeken.
- Druk op de knop Stoppen als u klaar bent met al uw acties.
DevTools toont u een overzicht van de geheugentoewijzing per functie. De standaardweergave is Heavy (Bottom Up) , waarbij bovenaan de functies worden weergegeven die het meeste geheugen hebben toegewezen.
Identificeer objecten die worden bewaard door JS-referentie
In het profiel Losgemaakte elementen ziet u losgemaakte elementen die blijven bestaan omdat er naar wordt verwezen door JavaScript-code.
Neem een profiel voor vrijstaande elementen op om de exacte HTML-knooppunten en het aantal knooppunten te bekijken.
Ontdek frequente afvalophalingen
Als het lijkt alsof uw pagina regelmatig wordt onderbroken, zijn er mogelijk problemen met de afvalinzameling.
U kunt Chrome Task Manager of tijdlijngeheugenopnamen gebruiken om frequente afvalverzamelingen te spotten. In Taakbeheer vertegenwoordigen vaak stijgende en dalende geheugen- of JavaScript- geheugenwaarden frequente afvalverzamelingen. In tijdlijnopnamen duiden frequent stijgende en dalende JS-heap- of knooppunttellinggrafieken op frequente ophaalacties.
Zodra u het probleem heeft geïdentificeerd, kunt u een toewijzingstijdlijnopname gebruiken om uit te vinden waar geheugen wordt toegewezen en welke functies de toewijzingen veroorzaken.