Web-Frameworks wie Angular, React, Vue und Svelte erleichtern das Schreiben und Warten komplexer Webanwendungen im großen Maßstab.
Diese Frameworks führen jedoch eine Abstraktionsebene über dem Anwendungsmodell des Browsers ein. Der von Entwicklern mit diesen Abstraktionen geschriebene Code wird in der Regel in unleserlichen, minimierten und gebündelten Code transkribiert. Daher kann es für Entwickler schwierig sein, die Leistungsfähigkeit der Entwicklertools zum Debuggen und Profilieren dieser Apps voll auszuschöpfen.
Wenn Sie beispielsweise eine Angular-Anwendung mit dem Bereich „Leistung“ in den Entwicklertools analysieren, wird Folgendes angezeigt:

So ist es schwierig, Leistungsengpässe in Ihrem Code zu erkennen. Es fehlt der Kontext der Framework-Konstrukte und ein Großteil der angezeigten Informationen besteht aus minimiertem Code. Außerdem ist es schwierig, zwischen der Aktivität, die direkt mit dem von Ihnen geschriebenen Code zusammenhängt, Framework-Interna und anderem Drittanbietercode zu unterscheiden, der möglicherweise auf derselben Seite ausgeführt wird.
Eine häufige Motivation für Autoren von Frameworks und Abstraktionen ist es, eigene DevTools-Erweiterungen zu implementieren, die Profiling-Daten in Bezug auf die Framework-Konzepte präsentieren. Diese Tools sind sehr nützlich, wenn Sie Anwendungen debuggen und profilieren, die mit einem bestimmten Framework erstellt wurden. In den meisten Fällen müssen Sie jedoch die Framework-Daten im Profiler Ihres Frameworks mit den Browserlaufzeitinformationen im Bereich Leistung der Entwicklertools korrelieren. Wenn diese beiden Datenquellen separat in unabhängigen Tools dargestellt werden, ist es schwierig, Engpässe zu erkennen und zu beheben, insbesondere wenn die Anwendung komplexer wird. Hier sehen Sie ein Beispiel für eine Profilvisualisierung im Angular DevTools Profiler:

Im Idealfall hätten Entwickler eine Ansicht, in der die beiden Datenquellen gemeinsam im selben Kontext auf derselben Zeitachse dargestellt werden.
Aus diesem Grund haben wir mit dem Angular-Team zusammengearbeitet, um Angular-Laufzeitdaten mithilfe der Performance-Panel-Extensibility-API direkt in das Leistungsbereich zu übertragen. In diesem Beitrag sehen wir uns an, was die API leisten kann und wie sie im Angular-Framework verwendet wurde, um dies zu erreichen. Die Implementierung kann als Beispiel für andere Frameworks und Abstraktionen dienen, die ihre Entwicklerfreundlichkeit verbessern möchten, indem sie eigene Tools instrumentieren und Entwicklern helfen, die Chrome-Entwicklertools verwenden.
Was ist die API zur Erweiterung des Bereichs „Leistung“?
Mit der API können Sie dem Trace im Bereich Leistung eigene Zeitmessungseinträge hinzufügen, die auf derselben Zeitachse wie die restlichen Browserdaten angezeigt werden. Dafür gibt es zwei Mechanismen:
- User Timing API
- Mit der
console.timeStamp
API
User Timing API
Sie können performance.mark
und performance.measure
verwenden, um die Einträge so hinzuzufügen:
// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();
// ... later in your code
performance.measure("Component rendering", {
start: renderStart,
detail: {
devtools: {
dataType: "track-entry",
track: "Components",
color: "secondary",
properties: [
["Render reason", "Props changed"],
["Priority", "low"]
],
}
}
});
Dadurch wird der Components-Track mit der Messung zu Ihrer Zeitachse hinzugefügt:

Mit dieser API können Sie die Einträge dem Puffer für die Leistungszeitachse hinzufügen und sie gleichzeitig in der Benutzeroberfläche des DevTools-Bereichs Leistung anzeigen lassen.
Weitere Informationen zu dieser API und zum devtools
-Objekt finden Sie in der Dokumentation.
Mit der console.timeStamp
API
Diese API ist eine schlanke Alternative zur User Timing API. Im vorherigen Beispiel könnte das so aussehen:
// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();
// ... later in your code
console.timeStamp(
"Component rendering",
/* start time */ renderStart,
/* end time (current time) */ undefined,
/* track name */ "Components",
/* track group name */ undefined,
/* color */ "secondary"
);
Diese API bietet eine leistungsstarke Methode zum Instrumentieren von Anwendungen. Im Gegensatz zur User Timing API-Alternative werden keine gepufferten Daten erstellt. Diese API fügt ausschließlich Daten in den Bereich „Leistung“ in den Entwicklertools ein. Das bedeutet, dass die Aufrufe der API keine Operationen ausführen, wenn in den Entwicklertools kein Trace aufgezeichnet wird. Dadurch ist sie deutlich schneller und für leistungsintensive Hotpaths geeignet. Die Entscheidung, Positionsargumente anstelle eines Objekts mit allen Anpassungsparametern zu verwenden, dient auch dazu, die API so schlank wie möglich zu halten.
So hat Angular die DevTools Extensibility API integriert
Wir sehen uns an, wie das Angular-Team die Extensibility API verwendet hat, um die Integration in die Chrome-Entwicklertools zu ermöglichen.
Overhead mit console.timestamp vermeiden
Die Instrumentierung von Angular mit der Extensibility API für den Leistungsbereich ist ab Version 20 verfügbar. Das gewünschte Detaillierungsniveau für Leistungsdaten in DevTools erfordert eine schnelle API. Daher wurde im Pull-Request (60217), mit dem die Instrumentierung hinzugefügt wurde, die console.timeStamp
API verwendet. Dadurch wird verhindert, dass die Laufzeitleistung der Anwendung durch den potenziellen Overhead der Profiling-API beeinträchtigt wird.
Instrumentierte Daten
Um ein gutes Bild davon zu vermitteln, welcher Angular-Code ausgeführt wird und warum er überhaupt ausgeführt wird, werden mehrere Teile der Start- und Rendering-Pipelines instrumentiert, darunter:
- Anwendungs- und Komponenten-Bootstrapping.
- Komponenten erstellen und aktualisieren
- Ausführung von Ereignis-Listenern und Lebenszyklus-Hooks.
- Viele andere (z. B. dynamische Komponentenerstellung und verzögertes Blockrendering).
Farbcodierung
Die Farbcodierung wird verwendet, um dem Entwickler die Kategorie zu signalisieren, in die ein bestimmter Messwerteintrag fällt. Die Farben für die Einträge, die die Ausführung von vom Entwickler geschriebenen TypeScript-Code kennzeichnen, unterscheiden sich beispielsweise von den Farben für Code, der vom Angular-Compiler generiert wurde.
Auf dem folgenden Screenshot sehen Sie, wie sich das auf die Darstellung auswirkt: Einstiegspunkte (z. B. Änderungserkennung und Komponentenverarbeitung) werden blau, generierter Code lila und TypeScript-Code (z. B. Event-Listener und Hooks) grün dargestellt.

Das color-Argument, das an die API übergeben wird, ist kein CSS-Farbwert, sondern ein semantisches Token, das einer Farbe zugeordnet ist, die der DevTools-Benutzeroberfläche entspricht. Die möglichen Werte sind primary
, secondary
und tertiary,
mit den entsprechenden Varianten -dark
und -light
sowie einer error
-Farbe.
Titelanzahl
Zum Zeitpunkt der Erstellung dieses Artikels werden alle Angular-Laufzeitdaten demselben Track hinzugefügt (mit „🅰️ Angular“ gekennzeichnet). Sie können dem Trace jedoch mehrere Tracks hinzufügen und die Tracks sogar gruppieren. Angenommen, die folgenden Aufrufe werden an die console.timeStamp
API gesendet:
console.timeStamp("Component 1", componentStart1, componentEnd1, "Components", "Client", "primary");
console.timeStamp("Component 2", componentStart2, componentEnd2, "Components", "Client", "primary");
console.timeStamp("Hook 1", hookStart, hookEnd, "Hooks", "Client", "primary");
console.timeStamp("Fetch data base", fetchStart, fetchEnd, "Server", "primary");
Die Daten werden dann so in Tracks organisiert:

Die Verwendung separater Tracks kann beispielsweise nützlich sein, wenn Sie asynchrone Aktivitäten, mehrere parallel ausgeführte Jobs oder einfach Aktivitätsgruppen haben, die so unterschiedlich sind, dass es sich lohnt, sie in verschiedenen Bereichen der Benutzeroberfläche zu trennen.
Warum ist das für Angular-Entwickler wichtig?
Ziel dieser direkten Integration ist es, eine intuitivere und umfassendere Leistungsanalyse zu ermöglichen. Wenn die internen Leistungsdaten von Angular direkt im Bereich **Leistung** angezeigt werden, erhalten Entwickler Folgendes:
- Bessere Sichtbarkeit: Angular-spezifische Leistungsereignisse wie das Rendern von Komponenten und Änderungsermittlungszyklen sind in der Browser-Zeitleiste sichtbar.
- Besseres Verständnis: Kontextreiche Informationen zu den internen Prozessen von Angular helfen Ihnen, Leistungsengpässe effektiver zu identifizieren.
Integration aktivieren
Die Verwendung der Extensibility API ist ab Angular 20 offiziell in Entwicklungs-Builds verfügbar. Dazu müssen Sie in Ihrer App oder in der DevTools-Konsole das globale Dienstprogramm `ng.enableProfiling()` ausführen. Weitere Informationen zur Integration finden Sie in der [Angular-Dokumentation](https://angular.dev/best-practices/profiling-with-chrome-devtools).
Weitere Hinweise
Dabei sind einige wichtige Aspekte zu berücksichtigen.
Quellzuordnungen und reduzierter Code:
Quellzuordnungen sind ein weit verbreitetes Tool, das die Lücke zwischen gebündeltem / reduziertem Code und dem entsprechenden erstellten Code schließen soll.
Sollten Quellzuordnungen das Problem mit reduziertem Code in gebündelten Apps nicht beheben?
Quellzuordnungen sind zwar hilfreich, aber sie beseitigen die Herausforderungen beim Profiling komplexer minimierter Web-Apps nicht vollständig. Mit Quellzuordnungen können die Entwicklertools den minimierten Code Ihrem ursprünglichen Quellcode zuordnen, was das Debugging erleichtert. Wenn Sie sich bei der Leistungsanalyse jedoch ausschließlich auf Quellzuordnungen verlassen, kann das einige Einschränkungen mit sich bringen. Mit Quellzuordnungen allein ist es beispielsweise schwierig, die Art und Weise festzulegen, wie Framework-Interna und erstellter Code visuell getrennt werden. Die Extensibility API bietet dagegen die Flexibilität, diese Unterscheidung vorzunehmen und sie so darzustellen, wie der Entwickler es für am besten hält.
Chrome-Entwicklertools-Erweiterungen:
Chrome-Erweiterungen, die die DevTools API verwenden, sind ein weit verbreitetes Tool zum Erweitern der Entwicklertools.
Sind spezielle Profiler (z. B. Chrome-Entwicklertools-Erweiterungen) jetzt unnötig oder nicht mehr empfehlenswert, da diese API verfügbar ist?
Nein. Diese API soll nicht die Entwicklung von speziellen Profilern wie Chrome-Entwicklertools-Erweiterungen ersetzen oder davon abraten. Sie können weiterhin spezielle Funktionen, Visualisierungen und Workflows bieten, die auf bestimmte Anforderungen zugeschnitten sind. Die Extensibility API für das Leistungsfeld soll eine nahtlose Integration benutzerdefinierter Daten in die Browser-Visualisierungen im Leistungsfeld ermöglichen.
Der weitere Weg
Die Aussicht auf die Extensibility API.
Mit mehr Frameworks und Abstraktionen arbeiten
Wir freuen uns, dass andere Frameworks und Abstraktionen die API übernehmen, um die Profilerstellung für ihre Entwickler zu verbessern. React hat beispielsweise eine experimentelle Übernahme der API für sein Framework implementiert. Diese Instrumentierung liefert Daten zum Rendern von Client- und Serverkomponenten sowie zu React-Planungs-APIs. Weitere Informationen
Produktions-Builds
Eines der Ziele dieser API ist es, mit Frameworks und Abstraktionsanbietern zusammenzuarbeiten, um die Instrumentierung in Produktions-Builds zu übernehmen und zu aktivieren. Dies könnte sich erheblich auf die Leistung der mit diesen Abstraktionen entwickelten Apps auswirken, da Entwickler die Anwendung so profilieren könnten, wie sie von ihren Nutzern verwendet wird. Wir sind der Meinung, dass die console.timeStamp
API aufgrund ihrer Geschwindigkeit und des geringen Overheads dafür geeignet ist. Derzeit wird jedoch noch mit der API experimentiert und es wird untersucht, welche Arten von Instrumentierungen für Entwickler skalierbarer und nützlicher sind.