Flame Charts und wie man sie liest
Der Performance Tab in Chrome DevTools ist berüchtigt dafür, schwer verständlich zu sein. Es gibt eine Fülle von Informationen über jedes kleine Stück Code und wiederum die Auswirkungen auf die jeweilige App. Das kann nützlich für das Identifizieren von Problemen sein, aber ebenso komplex.
In diesem Artikel wird der Performance Tab mit Fokus auf Flame Charts erläutert und Schritt für Schritt unter die Lupe genommen.
Wo in der Welt der Entwickler haben diese Charts überhaupt ihren Ursprung? Der Senior Performance Architect von Netflix hatte einmal ein Problem: Ihn erreichte ein Performance-Problem eines Kunden – und dieses generierte einen Stacktrace, der 591.622 Zeilen lang war.
Das ist praktisch unmöglich zu lesen – und in einem solchen Fall macht es wenig Sinn, den gesamten Stacktrace zu debuggen, um das Problem aufzuspüren. Da der Mensch ein visueller Lerner ist, lag deshalb die Idee nahe, diese Informationen auch auf visuelle Art und Weise darzustellen. Der Lösungsansatz war konkret also ein Prototyp einer Visualisierung, der die hierarchische Natur von Stacktraces ausnutzt, um gemeinsame Pfade zusammenzuführen. Durch die "warmen" Farben, die zur Visualisierung von CPU-"Hot Spots" dienen, wurde diese Visualisierung als "Flame Graph" bekannt.
Flame Graphs visualisieren, wo im Code die meiste Zeit verbracht wird – und damit nichts anderes als ihre Stacktraces. Alle ähnlichen Funktionsaufrufe werden entsprechend der Stack-Tiefe gruppiert. Auf diese Weise kann herausgefunden werden, wie lange eine bestimmte Funktion während des Profilings gelaufen ist. Das ist nützlich für Performance-Ingenieure, denn so können sie leichter entscheiden, welcher Teil einer Anwendung am ehesten optimiert werden muss.
Flame Graphs sind generell hilfreich, um Software zu verstehen: Komplexe Software hat Millionen von Codezeilen. Gerade für weniger erfahrene Entwickler kann es einschüchternd sein, so viele Codezeilen durchzugehen. Mit einem Flame Graph jedoch ist die große Codebasis auf die Funktionen eingegrenzt, die tatsächlich ausgeführt werden. Auch wird die Beziehung angezeigt, in der dies geschieht.
Flame Graphs vs Flame Charts
Besonders im Falle einer Multithreading-Anwendung, wie zum Beispiel einer CPU, sind Flame Graphs hilfreich. Wie aber kann diese Art der Visualisierung in einer Singlethread-Umgebung verwendet werden? Vor einiger Zeit öffnete jemand ein Ticket bei Google Chrome, um Flame Graphs zu implementieren. So wurde eine ganz eigene Version implementiert, bei der die Zeit auf die x-Achse gelegt wurde. Dieser Ansatz löst ein anderes Problem als klassische Flame Graphs. Um Verwirrung zu vermeiden hat Google sie Flame Charts genannt. Über Chrome ist das möglich, weil Javascript auf einem Singlethread läuft. Wenn Multithread-Anwendungen hingegen versuchen, Zeit zu visualisieren, sind sie nicht in der Lage, alle Threads zur gleichen Zeit darzustellen.
Chrome DevTools – Performance
Nun soll der Reiter "Performance" in Chrome DevTools betrachtet werden (die Registerkarte kann nur verwendet werden, wenn die Samples über die Schaltfläche "Aufnehmen" oder "Neu laden und aufnehmen" in den Performance-Tools aufgezeichnet werden). Sobald die Aufzeichnung einer bestimmten Zeitspanne vollständig ist, können die aufgezeichneten Informationen überprüft werden.
Timeline
Wenn das Kontrollkästchen "Screenshots" aktiviert ist, wird der oberste Abschnitt des Leistungsprofils als Timeline angezeigt. Dabei handelt es sich um eine Mini-Map mit allen Aktionen, die in der Zeit der Aufzeichnung stattgefunden haben. Diese gibt vor allem einen guten ersten Überblick und weist auf Problembereiche hin, auf die man sich zur Leistungssteigerung konzentrieren kann. In der Timeline kann hinein- oder herausgezoomt werden, indem mit der Maus nach oben oder unten gescrollt wird. Auch kann über Schieben der Marker der zu untersuchende Bereich markiert werden. Der Bereich unterhalb der Timeline zeigt immer die Details des ausgewählten Teils an.
Netzwerk
Einer der wichtigsten Abschnitte ist "Network", der alle Netzwerkaufrufe während der Aufzeichnung anzeigt. Hier sind verschiedene JavaScript- und CSS-Dateien zu sehen, die durch parallele Balken dargestellt werden. Der Netzwerkabschnitt ist insofern besonders, als dass er per Drag-&-drop erweitert und verkleinert werden kann.
Klickt man auf einen der Netzwerkaufrufe im Netzwerkbereich, werden über das Zusammenfassungsfeld detaillierte Informationen dazu anzeigt: Die aufgerufene URL, die Dauer des Ladevorgangs, aufgeteilt in Netzwerkübertragung und Ressourcenbelastung, die Art der Methode, die Priorität, die heruntergeladenen Daten usw.
Main Thread
Der nächste wichtige Abschnitt ist der Main Thread des Profils. Dieser zeigt Informationen in Form eines Flame Charts an. Jeder Balken in diesem Diagramm repräsentiert einen Funktionsaufruf des JavaScript-Codes, der über das Profil ausgeführt wurde.
Wenn ein Balken im Haupt-Thread-Abschnitt ausgewählt wird, ändert sich das Zusammenfassungsfeld und zeigt nun Informationen zu diesem Funktionsaufruf an: Die Zeilennummer, die insgesamt benötigte Zeit und andere Details. Auch verwendet die Tiefe des Aufrufbaums verschiedene Registerkarten im Zusammenfassungsfeld.
Das Flame Chart zeigt die Zeit als x-Achse und die Stack-Tiefe als y-Achse. Von links nach rechts ist ersichtlich, welche Aufgabe als erstes ausgeführt wurde usw. Jeder Balken repräsentiert ein Ereignis. Die Breite der Balken ist relativ zu der Zeit, die für eine bestimmte Funktion aufgewendet wurde. Die Balken in der zweiten und den folgenden Zeilen zeigen die Funktionen, die von der Hauptaktivität oder -funktion aufgerufen wurden. Das heißt, wenn Ereignisse übereinander dargestellt sind, haben die oberen Ereignisse die unteren Ereignisse verursacht. Diese Diagramme sind interaktiv, jeder Balken ist anklickbar. Durch Anklicken erhält man weitere Informationen über diesen Block in vier verschiedenen Ansichten darunter. Jede Ansicht gibt eine andere Perspektive auf die Aktivitäten.
In der Zusammenfassung ist ersichtlich, dass sich das Zusammenfassungsfeld ändert und nun Informationen über diesen Funktionsaufruf anzeigt: die Zeilennummer, die insgesamt benötigte Zeit und andere Details.
Wenn ein Task länger dauert als erwartet, stellt DevTools dies in einer Warnung auf der Registerkarte "Zusammenfassung" dar. Mit einem Klick auf app.js:94 gelangt man zu der fraglichen Codezeile. Dieser Prozess erleichtert die Problemfindung und anschließende Navigation.
Für weitere Informationen kann zu einer anderen Ansicht gewechselt werden. Für die Root-Aktivitäten, die die meiste Arbeit verursachen, wird beispielsweise der Call-Tree-Tab benötigt. Root-Aktivitäten sind all jene, die den Browser "arbeiten lassen". So wird zum Beispiel bei einem Klick auf eine Seite vom Browser eine Event-Aktivität ausgelöst.
Im Flame Chart des Hauptbereichs befinden sich die Root-Aktivitäten oben im Diagramm. Im Call Tree und Event Log sind es die Elemente der obersten Ebene.
Wenn die Aktivitäten angezeigt werden sollen, für die die meiste Zeit direkt aufgewendet wurde, ist die Ansicht "bottom-up" nötig.
Für die Ansicht der Aktivitäten in der Reihenfolge, in der sie während der Aufzeichnung aufgetreten sind, kann das Event Log zu Rate gezogen werden.
Timings
Einer der Abschnitte ist allen wichtigen Metriken gewidmet, die nach Ansicht der Mitarbeiter von Chrome wichtig sind, basierend auf der angegebenen Zeitleiste. Es wird angezeigt, an welchem Punkt First Paint (FP) und First Contentful paint(FCP) gemacht wurde.
Andere
Es gibt weitere Abschnitte im Performance-Tool, die hilfreich sein können. Die GPU-Aktivität ist im Abschnitt GPU zu finden; Raster-Aktivität unter Raster Section. Der Abschnitt "Interaktionen" kann verwendet werden, um Benutzerinteraktionen wie Tastatureingaben oder Mausklicks zu finden und zu analysieren, die während der Aufzeichnung stattfanden. Durch Anklicken der Checkbox "Memory" kann die Speichermatrix der Aufzeichnung eingesehen werden. Der Abschnitt "Frames" zeigt, wie lange ein Frame gedauert hat. Durch Bewegen des Mauszeigers über den Frame, wird ein Tooltip mit weiteren Informationen angezeigt.
Fazit
Es wird mit den vorgestellten Möglichkeiten deutlich, dass Flame Charts vielfältig einsetzbar sind und ein nützliches Tool zur Analyse von Informationen sind: vor allem können Probleme besser eingegrenzt werden. Hat man erst einmal den Dreh heraus, ist auch das Lesen kein Hexenwerk mehr und dem Einsatz steht nichts mehr im Wege.
Hinweis: Die dargestellten Informationen des Chrome DevTools Performance Tabs basieren auf Chrome Version 91.0.