Speicherprobleme beheben

Hier erfährst du, wie du mit Chrome und den Entwicklertools Speicherprobleme findest, die sich auf die Seitenleistung auswirken, z. B. Speicherlecks, übermäßiger Arbeitsspeicher und häufige automatische Speicherbereinigungen.

Zusammenfassung

  • Finden Sie mit dem Task-Manager von Chrome heraus, wie viel Arbeitsspeicher Ihre Seite derzeit belegt.
  • Die Arbeitsspeichernutzung im Zeitverlauf mit Zeitachsenaufzeichnungen visualisieren.
  • Getrennte DOM-Bäume (eine häufige Ursache von Speicherlecks) mit Heap-Snapshots identifizieren.
  • Durch Aufzeichnungen über die Zuordnungs-Zeitachse können Sie feststellen, wann in Ihrem JS-Heap neuer Arbeitsspeicher zugewiesen wird.

Überblick

Gemäß dem RAIL-Leistungsmodell sollten Sie bei Ihren Bemühungen zur Leistungssteigerung den Schwerpunkt auf Ihre Nutzer legen.

Probleme mit dem Gedächtnis sind wichtig, weil sie oft von den Nutzenden wahrgenommen werden. Nutzer können Gedächtnisprobleme so wahrnehmen:

  • Die Leistung einer Seite verschlechtert sich mit der Zeit immer weiter. Dies ist möglicherweise ein Symptom für ein Speicherleck. Ein Speicherleck liegt vor, wenn ein Fehler auf der Seite dazu führt, dass die Seite im Laufe der Zeit immer mehr Arbeitsspeicher belegt.
  • Die Leistung einer Seite ist durchweg schlecht. Das ist möglicherweise ein Symptom von aufgeblähtem Gedächtnis. Von einer aufgeblähten Speichernutzung wird gesprochen, wenn eine Seite mehr Arbeitsspeicher benötigt, als für eine optimale Seitengeschwindigkeit erforderlich ist.
  • Die Leistung einer Seite verzögert sich oder scheint häufig zu pausieren. Dies ist möglicherweise ein Symptom für häufige automatische Speicherbereinigungen. Bei der automatischen Speicherbereinigung gibt der Browser Arbeitsspeicher frei. Der Browser entscheidet, wann dies geschieht. Während der Erfassung wird die gesamte Skriptausführung angehalten. Wenn der Browser also häufig die automatische Speicherbereinigung durchführt, wird die Skriptausführung häufig angehalten.

Erinnerung aufgebläht: Wie viel ist „zu viel“?

Ein Speicherleck ist einfach zu definieren. Wenn eine Website immer mehr Arbeitsspeicher verbraucht, ist ein Speicherleck aufgetreten. Aber es ist etwas schwieriger, eine überflüssige Erinnerung festzuhalten. Was bedeutet „zu viel Arbeitsspeicher“?

Es gibt hier keine genauen Zahlen, da unterschiedliche Geräte und Browser unterschiedliche Funktionen haben. Dieselbe Seite, die auf einem High-End-Smartphone reibungslos läuft, kann auf einem Low-End-Smartphone abstürzen.

Entscheidend ist hier, das RAIL-Modell zu verwenden und sich auf Ihre Nutzenden zu konzentrieren. Finden Sie heraus, welche Geräte bei Ihren Nutzern beliebt sind, und testen Sie Ihre Seite dann auf diesen Geräten. Wenn die Nutzererfahrung immer wieder schlecht ist, überschreitet die Seite möglicherweise die Speicherkapazität dieser Geräte.

Arbeitsspeichernutzung in Echtzeit mit dem Task-Manager von Chrome überwachen

Verwenden Sie den Task-Manager von Chrome als Ausgangspunkt für die Untersuchung von Speicherproblemen. Der Task-Manager ist ein Echtzeitmonitor, der Ihnen anzeigt, wie viel Speicher eine Seite derzeit verwendet.

  1. Drücken Sie Umschalttaste + Esc oder rufen Sie das Chrome-Hauptmenü auf und wählen Sie Weitere Tools > Task-Manager aus, um den Task-Manager zu öffnen.

    Task-Manager öffnen

  2. Klicken Sie mit der rechten Maustaste auf die Kopfzeile der Tabelle im Task-Manager und aktivieren Sie JavaScript-Arbeitsspeicher.

    JavaScript-Speicher aktivieren

Diese beiden Spalten geben unterschiedliche Informationen zur Speichernutzung durch Ihre Seite an:

  • Die Spalte Arbeitsspeicher stellt den nativen Arbeitsspeicher dar. DOM-Knoten werden im nativen Arbeitsspeicher gespeichert. Wenn dieser Wert steigt, werden DOM-Knoten erstellt.
  • Die Spalte JavaScript Memory (JavaScript-Speicher) stellt den JS-Heap dar. Diese Spalte enthält zwei Werte. Der Wert, für den Sie sich interessieren, ist die Live-Zahl (die Zahl in Klammern). Die Live-Zahl gibt an, wie viel Speicher die erreichbaren Objekte auf Ihrer Seite belegen. Wenn diese Anzahl steigt, werden entweder neue Objekte erstellt oder die Anzahl der vorhandenen Objekte wird größer.

Speicherlecks mit Leistungsaufzeichnungen visualisieren

Sie können den Bereich „Leistung“ auch als weiteren Ausgangspunkt für Ihre Prüfung verwenden. Im Bereich „Leistung“ können Sie die Arbeitsspeichernutzung einer Seite im Zeitverlauf visualisieren.

  1. Öffnen Sie in den Entwicklertools den Bereich Leistung.
  2. Klicken Sie das Kästchen Arbeitsspeicher an.
  3. Nehmen Sie eine Aufnahme vor.

Sehen Sie sich den folgenden Code an, um Performance-Memory-Aufzeichnungen zu veranschaulichen:

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);

Jedes Mal, wenn die Schaltfläche, auf die im Code verwiesen wird, gedrückt wird, werden zehntausend div-Knoten an den Dokumenttext angehängt und ein String mit einer Million x-Zeichen wird auf das x-Array übertragen. Wenn Sie diesen Code ausführen, wird eine Zeitachsenaufzeichnung wie im folgenden Screenshot erstellt:

Beispiel für einfaches Wachstum

Zuerst eine Erläuterung der Benutzeroberfläche. Das HEAP-Diagramm im Bereich Übersicht (unter NET) stellt den JS-Heap dar. Unterhalb des Bereichs Übersicht befindet sich der Bereich Zähler. Hier sehen Sie die Arbeitsspeichernutzung aufgeschlüsselt nach JS-Heap (wie beim HEAP-Diagramm im Übersichtsbereich), Dokumenten, DOM-Knoten, Listenern und GPU-Arbeitsspeicher. Wenn Sie ein Kästchen deaktivieren, wird es in der Grafik ausgeblendet.

Nun folgt eine Analyse des Codes im Vergleich zum Screenshot. Wenn Sie sich den Knotenzähler (das grüne Diagramm) ansehen, sehen Sie, dass er sauber mit dem Code übereinstimmt. Die Knotenanzahl erhöht sich in einzelnen Schritten. Jede Erhöhung der Knotenanzahl ist ein Aufruf von grow(). Die JS-Heap-Grafik (die blaue Grafik) ist nicht so einfach. Gemäß den Best Practices ist der erste Dip tatsächlich eine erzwungene automatische Speicherbereinigung, die durch Klicken auf die Schaltfläche automatische Speicherbereinigung erreicht wird. Im Verlauf der Aufzeichnung können Sie sehen, dass die JS-Heap-Größe ansteigt. Das ist normal und zu erwarten: Der JavaScript-Code erstellt die DOM-Knoten bei jedem Klick auf eine Schaltfläche und leistet sehr viel Arbeit, wenn er den String von einer Million Zeichen erzeugt. Das Entscheidende ist hier, dass der JS-Heap höher endet, als er begonnen hat (der „Anfang“ hier ist der Punkt nach der erzwungenen automatischen Speicherbereinigung). Wenn Sie in der Praxis dieses Muster einer zunehmenden JS-Heap-Größe oder Knotengröße sehen würden, würde dies möglicherweise auf ein Speicherleck hindeuten.

Getrennte DOM-Baum-Speicherlecks mit Heap-Snapshots erkennen

Ein DOM-Knoten kann nur dann automatisch bereinigt werden, wenn es weder von der DOM-Struktur der Seite noch vom JavaScript-Code Verweise darauf gibt. Ein Knoten gilt als „getrennt“, wenn er aus der DOM-Baumstruktur entfernt wird. Einige JavaScript-Elemente verweisen jedoch noch auf ihn. Getrennte DOM-Knoten sind eine häufige Ursache von Speicherlecks. In diesem Abschnitt erfahren Sie, wie Sie mit den Heap-Profilern der Entwicklertools getrennte Knoten identifizieren.

Hier ist ein einfaches Beispiel für getrennte DOM-Knoten.

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);

Durch Klicken auf die Schaltfläche, auf die im Code verwiesen wird, wird ein ul-Knoten mit zehn untergeordneten li-Elementen erstellt. Im Code wird auf diese Knoten verwiesen, sie sind aber nicht im DOM-Baum vorhanden. Daher werden sie getrennt.

Heap-Snapshots sind eine Möglichkeit, getrennte Knoten zu identifizieren. Wie der Name schon sagt, zeigen Heap-Snapshots, wie sich der Arbeitsspeicher zum Zeitpunkt des Snapshots auf die JS-Objekte und DOM-Knoten Ihrer Seite verteilt.

Wenn Sie einen Snapshot erstellen möchten, öffnen Sie die Entwicklertools, gehen Sie zum Bereich Arbeitsspeicher, wählen Sie das Optionsfeld Heap-Snapshot aus und klicken Sie auf Snapshot erstellen.

Heap-Snapshot erstellen

Es kann einige Zeit dauern, bis der Snapshot verarbeitet und geladen ist. Sobald der Vorgang abgeschlossen ist, wählen Sie ihn im linken Bereich aus (mit dem Namen HEAP SNAPSHOTS).

Geben Sie in das Textfeld Klassenfilter Detached ein, um nach losgelösten DOM-Bäumen zu suchen.

Filtern nach getrennten Knoten

Maximieren Sie die Zeichen, um einen frei stehenden Baum zu untersuchen.

freistehenden Baum untersuchen

Gelb hervorgehobene Knoten haben direkte Verweise vom JavaScript-Code auf sie. Rot hervorgehobene Knoten haben keine direkten Verweise. Sie sind nur lebendig, weil sie Teil des Baums des gelben Knotens sind. Im Allgemeinen sollten Sie sich auf die gelben Knoten konzentrieren. Korrigieren Sie Ihren Code so, dass der gelbe Knoten nicht länger als nötig aktiv ist. Außerdem entfernen Sie die roten Knoten, die zum Baum des gelben Knotens gehören.

Klicken Sie auf einen gelben Knoten, um ihn weiter zu untersuchen. Im Bereich Objekte finden Sie weitere Informationen zu dem Code, der darauf verweist. Im folgenden Screenshot sehen Sie beispielsweise, dass die Variable detachedTree auf den Knoten verweist. Um dieses spezielle Speicherleck zu beheben, untersuchen Sie den Code, der detachedTree verwendet, und achten Sie darauf, dass der Verweis auf den Knoten entfernt wird, wenn er nicht mehr benötigt wird.

Ein gelber Knoten wird untersucht

JS-Heap-Speicherlecks mit Zuordnungszeiträumen identifizieren

Die Allocation Timeline ist ein weiteres Tool, mit dem Sie Speicherlecks in Ihrem JS-Heap aufspüren können.

Die Zuordnungszeitachse veranschaulicht den folgenden Code:

var x = [];

function grow() {
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

Jedes Mal, wenn die im Code referenzierte Schaltfläche gedrückt wird, wird ein String von einer Million Zeichen in das Array x eingefügt.

Wenn Sie eine Zeitleiste für die Zuweisung aufzeichnen möchten, öffnen Sie die Entwicklertools, gehen Sie zum Bereich Profiles (Profile), wählen Sie das Optionsfeld Record Allocation Timeline (Zeitleiste für die Zuordnung aufzeichnen) aus und klicken Sie auf die Schaltfläche Start. Führen Sie die Aktion aus, die das Speicherleck Ihrer Meinung nach verursacht, und klicken Sie auf die Schaltfläche Aufzeichnung beenden (Schaltfläche zum Beenden der Aufnahme), wenn Sie fertig sind.

Achten Sie bei der Aufnahme wie im Screenshot unten darauf, ob auf der Zuordnungszeitachse blaue Balken angezeigt werden.

neue Zuweisungen

Diese blauen Balken stellen neue Arbeitsspeicherzuweisungen dar. Diese neuen Arbeitsspeicherzuweisungen sind Kandidaten für Speicherlecks. Sie können einen Balken heranzoomen, um den Bereich Konstruktor so zu filtern, dass nur Objekte angezeigt werden, die während des angegebenen Zeitraums zugewiesen wurden.

Vergrößerte Zuweisungszeitachse

Maximieren Sie das Objekt und klicken Sie auf seinen Wert, um im Bereich Objekt weitere Details zum Objekt aufzurufen. Im Screenshot unten sehen Sie beispielsweise in den Details des neu zugewiesenen Objekts, dass es der Variable x im Bereich Window zugeordnet wurde.

Objektdetails

Arbeitsspeicherzuweisung nach Funktion prüfen

Verwenden Sie den Typ Stichprobenerhebung für die Zuordnung im Bereich Arbeitsspeicher, um die Arbeitsspeicherzuweisung nach JavaScript-Funktion anzusehen.

Profiler für Datensatzzuweisungen

  1. Wählen Sie das Optionsfeld Allocation Sampling (Stichprobenerhebung für Zuordnung) aus. Wenn es auf der Seite einen Worker gibt, können Sie diesen über das Drop-down-Menü neben der Schaltfläche Start als Profilerstellungsziel auswählen.
  2. Drücken Sie die Taste Start.
  3. Führen Sie die Aktionen auf der Seite aus, die Sie untersuchen möchten.
  4. Wenn Sie alle Aktionen ausgeführt haben, drücken Sie die Taste Stopp.

Die Entwicklertools zeigen eine Aufschlüsselung der Arbeitsspeicherzuweisung nach Funktion. Die Standardansicht ist Heavy (Bottom Up). Hier werden oben die Funktionen angezeigt, die den meisten Arbeitsspeicher zugewiesen haben.

Zuweisungsprofil

Häufige automatische Speicherbereinigungen erkennen

Wenn Ihre Seite häufig pausiert wird, liegen möglicherweise Probleme mit der automatischen Speicherbereinigung vor.

Sie können entweder den Chrome Task-Manager oder Aufzeichnungen von Zeitachsen-Speicher verwenden, um häufige automatische Speicherbereinigungen zu erkennen. Im Task-Manager stellen häufig steigende und abfallende Werte für Arbeitsspeicher oder JavaScript-Arbeitsspeicher eine häufige automatische Speicherbereinigung dar. In Zeitachsenaufzeichnungen weisen häufig steigende und abfallende JS-Heap- oder Knotenanzahl-Diagramme auf häufige automatische Speicherbereinigungen hin.

Sobald Sie das Problem identifiziert haben, können Sie eine Aufzeichnung der Zeitleiste verwenden, um herauszufinden, wo Arbeitsspeicher zugewiesen wird und welche Funktionen die Zuweisungen verursachen.