In Chrome 102 sehen Sie in den Entwicklertools den neuen experimentellen Bereich Leistungsstatistiken. In diesem Beitrag erläutern wir nicht nur, warum wir an einem neuen Panel gearbeitet haben, sondern auch, welche technischen Herausforderungen wir dabei gemeistert haben und welche Entscheidungen wir getroffen haben.
Warum ein weiteres Steuerfeld erstellen?
Falls Sie es noch nicht gesehen haben: Wir haben ein Video veröffentlicht, in dem wir erklären, warum wir den Bereich „Leistungsstatistiken“ entwickelt haben und wie Sie damit umsetzbare Informationen zur Leistung Ihrer Website erhalten.
Das vorhandene Leistungspanel ist eine gute Ressource, wenn Sie alle Daten für Ihre Website an einem Ort sehen möchten. Wir haben jedoch festgestellt, dass es etwas überwältigend sein kann. Wenn du kein Experte für die Leistung bist, ist es schwierig zu wissen, worauf du genau achten musst und welche Teile der Aufnahme relevant sind.
Im Bereich „Statistiken“ können Sie sich weiterhin eine Zeitachse Ihres Tracings ansehen und die Daten prüfen. Außerdem erhalten Sie eine praktische Liste der wichtigsten „Statistiken“, die sich in den DevTools ansehen sollten. So lassen sich unter anderem Probleme wie renderblockierende Anfragen, Layoutänderungen und lange Aufgaben erkennen, die sich negativ auf die Seitenladeleistung und insbesondere auf die Core Web Vitals (CWV) Ihrer Website auswirken können. Neben der Kennzeichnung von Problemen erhalten Sie in den Leistungsdaten umsetzbare Vorschläge zur Verbesserung Ihrer CWV-Werte sowie Links zu weiteren Ressourcen und Dokumentationen.
Dieser Bereich ist experimentell und wir würden uns über Feedback freuen. Bitte teilen Sie uns mit, wenn Sie auf Fehler stoßen oder Funktionen anfordern möchten, die Ihnen bei der Optimierung der Leistung Ihrer Website helfen könnten.
So haben wir Leistungsstatistiken entwickelt
Wie der Rest von DevTools wurde auch Performance Insights in TypeScript erstellt. Für die Benutzeroberfläche wurden Webkomponenten mit lit-html verwendet. Der Unterschied zu Performance Insights besteht darin, dass die primäre Benutzeroberfläche ein HTML-canvas
-Element ist und die Zeitachse auf diesem Canvas gezeichnet wird. Die größte Komplexität entsteht durch die Verwaltung dieses Canvas: Es geht nicht nur darum, die richtigen Details an der richtigen Stelle zu zeichnen, sondern auch um die Verwaltung von Mausereignissen (z. B.: Wo hat der Nutzer auf dem Canvas geklickt? Haben sie auf ein von uns gezeichnetes Ereignis geklickt?) und dafür sorgen, dass der Canvas effektiv neu gerendert wird.
Mehrere Tracks auf einem einzigen Canvas
Für eine bestimmte Website gibt es mehrere „Tracks“, die wir rendern möchten. Jeder Track steht für eine andere Datenkategorie. Im Bereich „Statistiken“ werden beispielsweise standardmäßig drei Tracks angezeigt:
Wir werden das Panel kontinuierlich um weitere Funktionen ergänzen und voraussichtlich auch weitere Tracks hinzufügen.
Ursprünglich wollten wir für jeden dieser Tracks eine eigene <canvas>
rendern, damit die Hauptansicht aus mehreren vertikal gestapelten Canvas-Elementen besteht. Das würde das Rendern auf Spurebene vereinfachen, da jeder Track einzeln gerendert werden könnte und es keine Gefahr gäbe, dass ein Track außerhalb seiner Grenzen gerendert wird. Leider hat dieser Ansatz zwei Hauptprobleme:
Das (Wieder-)Rendern von canvas
-Elementen ist sehr aufwendig. Mehrere Canvasse sind aufwendiger als ein einzelner Canvas, auch wenn dieser größer ist.
Das Rendern von Overlays, die sich über mehrere Tracks erstrecken (z. B. vertikale Linien, um Ereignisse wie die FCP-Zeit zu markieren), wird komplex: Wir müssen auf mehreren Canvases rendern und dafür sorgen, dass sie alle zusammen und richtig ausgerichtet werden.
Da wir nur eine canvas
für die gesamte Benutzeroberfläche verwenden, mussten wir herausfinden, wie wir dafür sorgen können, dass jeder Track an den richtigen Koordinaten gerendert wird und nicht in einen anderen Track überläuft. Wenn ein bestimmter Track beispielsweise 100 Pixel hoch ist, können wir nicht zulassen, dass etwas mit einer Höhe von 120 Pixeln gerendert wird und in den darunter liegenden Track überläuft. Zur Behebung dieses Problems können wir clip
verwenden. Bevor wir jeden Track rendern, zeichnen wir ein Rechteck, das das sichtbare Trackfenster darstellt. Dadurch wird sichergestellt, dass alle Pfade, die außerhalb dieser Grenzen gezeichnet werden, vom Canvas abgeschnitten werden.
canvasContext.beginPath();
canvasContext.rect(
trackVisibleWindow.x, trackVisibleWindow.y, trackVisibleWindow.width, trackVisibleWindow.height);
canvasContext.clip();
Außerdem sollte jeder Track seine vertikale Position nicht kennen müssen: Jeder Track sollte sich so rendern, als würde er bei (0, 0) gerendert. Wir haben eine Komponente auf höherer Ebene (die wir TrackManager
nennen), um die Gesamtposition des Tracks zu verwalten. Dazu können Sie translate
verwenden, um den Canvas um eine bestimmte (x, y)-Position zu verschieben. Beispiel:
canvasContext.translate(0, 10); // Translate by 10px in the y direction
canvasContext.rect(0, 0, 10, 10); // draw a rectangle at (0, 0) that’s 10px high and wide
Obwohl im rect
-Code 0, 0
als Position festgelegt ist, wird das Rechteck durch die angewendete Gesamttranslation an 0, 10
gerendert. So können wir auf Spurebene arbeiten, als würden wir bei (0, 0) rendern, und unseren Spurmanager so übersetzen lassen, dass jeder Track korrekt unter dem vorherigen gerendert wird.
Off-Screen-Canvasse für Titel und Highlights
Das Canvas-Rendering ist relativ aufwendig. Wir möchten jedoch dafür sorgen, dass das Steuerfeld „Statistiken“ flüssig und reaktionsschnell bleibt. Manchmal ist es unvermeidlich, den gesamten Canvas noch einmal zu rendern. Das ist beispielsweise der Fall, wenn Sie die Zoomstufe ändern. Das erneute Rendern des Canvas ist besonders aufwendig, da Sie nicht nur einen kleinen Teil davon neu rendern können, sondern den gesamten Canvas löschen und neu zeichnen müssen. Das ist anders als beim DOM-Neu-Rendering, bei dem Tools die erforderliche Mindestarbeit berechnen können, anstatt alles zu entfernen und noch einmal von vorn anzufangen.
Ein Bereich, in dem wir visuelle Probleme festgestellt haben, war das Hervorheben. Wenn Sie den Mauszeiger auf Messwerte im Bereich bewegen, werden sie in der Zeitachse hervorgehoben. Wenn Sie den Mauszeiger auf eine Statistik für ein bestimmtes Ereignis bewegen, wird dieses Ereignis blau umrandet.
Diese Funktion wurde zuerst so implementiert, dass eine Mausbewegung über ein Element erkannt und dann direkt auf dem Haupt-Canvas ein Highlight gezeichnet wurde. Das Problem tritt auf, wenn wir die Markierung entfernen müssen: Die einzige Option ist, alles neu zu zeichnen. Es ist nicht möglich, den Bereich, in dem sich der Akzent befand, einfach neu zu zeichnen (nicht ohne große strukturelle Änderungen). Aber den gesamten Canvas neu zu zeichnen, nur weil wir einen blauen Rahmen um ein Element entfernen möchten, erschien uns übertrieben. Außerdem gab es visuelle Verzögerungen, wenn Sie den Mauszeiger schnell über verschiedene Elemente bewegten, um mehrere Highlights in schneller Folge auszulösen.
Um das zu beheben, haben wir unsere Benutzeroberfläche in zwei nicht sichtbare Canvasse unterteilt: den „Haupt-Canvas“, auf dem die Titel gerendert werden, und den „Highlights-Canvas“, auf dem die Highlights gezeichnet werden. Anschließend werden diese Canvases in den einzelnen Canvas kopiert, der dem Nutzer auf dem Bildschirm angezeigt wird. Wir können die Methode drawImage
auf einen Canvas-Kontext anwenden, der einen anderen Canvas als Quelle haben kann.
Wenn Sie das tun, wird das Haupt-Canvas nicht neu gezeichnet, wenn Sie ein Highlight entfernen. Stattdessen können Sie das Canvas auf dem Bildschirm löschen und dann das Haupt-Canvas in das sichtbare Canvas kopieren. Das Kopieren eines Canvas ist kostengünstig, das Zeichnen ist dagegen teuer. Indem wir Highlights auf ein separates Canvas verschieben, vermeiden wir diese Kosten, wenn wir Highlights ein- und ausschalten.
Umfassend getestetes Trace-Parsing
Einer der Vorteile beim Erstellen einer neuen Funktion von Grund auf besteht darin, dass Sie die zuvor getroffenen technischen Entscheidungen überdenken und Verbesserungen vornehmen können. Unter anderem wollten wir unseren Code explizit in zwei fast vollständig getrennte Teile aufteilen:
Parsen Sie die Tracedatei und ziehen Sie die erforderlichen Daten heraus. Tracks rendern
Durch die Trennung des Parsings (Teil 1) von der UI-Arbeit (Teil 2) konnten wir ein solides Parsing-System entwickeln. Jeder Trace wird durch eine Reihe von Handlern geführt, die für unterschiedliche Aufgaben verantwortlich sind: Ein LayoutShiftHandler
berechnet alle Informationen, die wir für Layoutänderungen benötigen, und ein NetworkRequestsHandler
kümmert sich ausschließlich um das Abrufen von Netzwerkanfragen. Der explizite Parseschritt, bei dem verschiedene Handler für verschiedene Teile des Logs verantwortlich sind, war ebenfalls von Vorteil: Das Parsen von Protokollen kann sehr kompliziert werden und es ist hilfreich, sich jeweils auf ein Problem zu konzentrieren.
Außerdem konnten wir unsere Trace-Analyse umfassend testen, indem wir Aufzeichnungen in DevTools erstellt, gespeichert und dann als Teil unserer Testsuite geladen haben. Das ist großartig, weil wir mit echten Traces testen können und nicht riesige Mengen an gefälschten Trace-Daten ansammeln müssen, die möglicherweise veraltet sind.
Screenshot-Tests für Canvas-UI
Bleiben wir beim Thema Tests: Normalerweise testen wir unsere Frontend-Komponenten, indem wir sie im Browser rendern und dafür sorgen, dass sie sich wie erwartet verhalten. Wir können Klickereignisse senden, um Aktualisierungen auszulösen, und prüfen, ob das von den Komponenten generierte DOM korrekt ist. Dieser Ansatz funktioniert für uns gut, aber nicht beim Rendern in einen Canvas. Es gibt keine Möglichkeit, einen Canvas zu prüfen und festzustellen, was dort gezeichnet wird. Daher ist unser üblicher Ansatz, zuerst zu rendern und dann abzufragen, nicht geeignet.
Um eine gewisse Testabdeckung zu erreichen, haben wir uns für Screenshot-Tests entschieden. Bei jedem Test wird ein Canvas gestartet, der zu testende Track gerendert und dann ein Screenshot des Canvas-Elements aufgenommen. Dieser Screenshot wird dann in unserer Codebasis gespeichert. Bei zukünftigen Tests wird der gespeicherte Screenshot mit dem generierten Screenshot verglichen. Wenn die Screenshots unterschiedlich sind, schlägt der Test fehl. Wir stellen auch ein Flag bereit, mit dem der Test ausgeführt und ein Screenshot-Update erzwungen werden kann, wenn wir das Rendering absichtlich geändert haben und der Test aktualisiert werden muss.
Screenshot-Tests sind nicht perfekt und etwas ungenau. Sie können nur testen, ob die gesamte Komponente wie erwartet gerendert wird, und nicht spezifischere Behauptungen. Anfangs haben wir sie zu oft verwendet, um sicherzustellen, dass jede einzelne Komponente (HTML oder Canvas) korrekt gerendert wird. Das hat unsere Testsuite drastisch verlangsamt und zu Problemen geführt, bei denen kleine, fast irrelevante Änderungen an der Benutzeroberfläche (z. B. subtile Farbänderungen oder das Hinzufügen von Rändern zwischen Elementen) dazu geführt haben, dass mehrere Screenshots fehlgeschlagen sind und aktualisiert werden mussten. Wir haben die Verwendung von Screenshots jetzt reduziert und verwenden sie nur noch für Canvas-basierte Komponenten. Dieses Gleichgewicht hat sich bisher bewährt.
Fazit
Die Entwicklung des neuen Bereichs „Leistungsstatistiken“ war für das Team eine sehr angenehme und lehrreiche Erfahrung. Wir haben viel über Trace-Dateien, die Arbeit mit Canvas und vieles mehr gelernt. Wir hoffen, dass euch das neue Steuerfeld gefällt. Wir freuen uns auf euer Feedback.
Weitere Informationen zum Bereich „Leistungsstatistiken“ finden Sie unter Leistungsstatistiken: Umsetzbare Informationen zur Leistung Ihrer Website.
Vorschaukanäle herunterladen
Verwenden Sie als Standard-Entwicklungsbrowser Chrome Canary, Chrome Dev oder Chrome Beta. Diese Vorabversionen bieten Ihnen Zugriff auf die neuesten DevTools-Funktionen, ermöglichen es Ihnen, innovative Webplattform-APIs zu testen, und helfen Ihnen, Probleme auf Ihrer Website zu finden, bevor Ihre Nutzer sie bemerken.
Chrome-Entwicklertools-Team kontaktieren
Mit den folgenden Optionen können Sie über neue Funktionen, Updates oder andere Themen im Zusammenhang mit den DevTools sprechen.
- Senden Sie uns Feedback und Funktionsanfragen unter crbug.com.
- Melden Sie ein DevTools-Problem über das Dreipunkt-Menü Weitere Optionen > Hilfe > DevTools-Problem melden.
- Tweeten Sie an @ChromeDevTools.
- Hinterlassen Sie Kommentare unter den YouTube-Videos zu den Neuigkeiten in den DevTools oder den YouTube-Videos mit Tipps zu den DevTools.