Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

Navigations- und Ressourcen-Timings

Navigations-Timings sind Metriken zur Messung der Navigationsereignisse eines Browsers. Ressourcen-Timings sind detaillierte Netzwerk-Timing-Messungen zum Laden von Ressourcen einer Anwendung. Beide bieten dieselben schreibgeschützten Eigenschaften, aber die Navigations-Timing misst die Zeitmessungen des Hauptdokuments, während die Ressourcen-Timing die Zeiten für alle vom Hauptdokument aufgerufenen Ressourcen und die angeforderten Ressourcen der Ressourcen bereitstellt.

Die generellen Performance-Timings unten wurden zugunsten der Performance Entry API, die es ermöglicht, entlang des Navigations- und Ressourcenladeprozesses Zeiten zu markieren und zu messen, als veraltet markiert. Obwohl veraltet, werden sie in allen Browsern unterstützt.

Performance Timings

Die performanceTiming API, eine JavaScript-API zur Messung der Ladeperformance der angeforderten Seite, ist veraltet, wird jedoch in allen Browsern unterstützt. Sie wurde durch die performanceNavigationTiming API ersetzt.

Die Performance-Timing-API bot schreibgeschützte Zeiten in Millisekunden(ms), die beschreiben, wann jeder Punkt im Seitenladeprozess erreicht wurde. Wie im Bild unten gezeigt, geht der Navigationsprozess von navigationStart, unloadEventStart, unloadEventEnd, redirectStart, redirectEnd, fetchStart, domainLookupStart, domainLookupEnd, connectStart, connectEnd, secureConnectionStart, requestStart, responseStart, responseEnd, domLoading, domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd, domComplete, loadEventStart und loadEventEnd.

Navigation Timing Ereignismetriken

Mit den obigen Metriken und etwas Mathematik können wir viele wichtige Metriken berechnen, wie Time to First Byte, Seitenladezeit, DNS-Abfrage und ob die Verbindung sicher ist.

Um den Zeitaufwand für alle Schritte zu messen, bietet die Performance-Timing-API schreibgeschützte Messungen der Navigations-Timings. Um unsere App-Timings zu betrachten und zu erfassen, geben wir ein:

js
let time = window.performance.timing;

Wir können dann die Ergebnisse nutzen, um zu messen, wie gut unsere App funktioniert.

Eingeben von window.performance.timing in der Konsole listet alle Timings in der PerformanceNavigationTiming-Schnittstelle auf

Die Reihenfolge ist:

Performance Timings Details
[`navigationStart`](/de/docs/Web/API/PerformanceTiming/navigationStart) Wenn die Aufforderung zum Entladen des vorherigen Dokuments im selben Browsing-Kontext endet. Wenn es kein vorheriges Dokument gibt, wird dieser Wert derselbe sein wie PerformanceTiming.fetchStart.
[`secureConnectionStart`](/de/docs/Web/API/PerformanceTiming/secureConnectionStart) Wenn der sichere Verbindungs-Handshake beginnt. Wenn keine solche Verbindung angefordert wird, wird 0 zurückgegeben.
[`redirectStart`](/de/docs/Web/API/PerformanceTiming/redirectStart) Wenn die erste HTTP-Weiterleitung beginnt. Wenn es keine Weiterleitung gibt oder eine der Weiterleitungen nicht vom selben Ursprung stammt, ist der zurückgegebene Wert 0.
[`redirectEnd`](/de/docs/Web/API/PerformanceTiming/redirectEnd)

Wenn die letzte HTTP-Weiterleitung abgeschlossen ist, also wenn das letzte Byte der HTTP-Antwort empfangen wurde. Wenn es keine Weiterleitung gibt oder eine der Weiterleitungen nicht vom selben Ursprung stammt, ist der zurückgegebene Wert 0.

[`connectEnd`](/de/docs/Web/API/PerformanceTiming/connectEnd) Wenn die Netzwerkverbindung geöffnet ist. Wenn die Transportschicht einen Fehler meldet und die Verbindung erneut gestartet wird, wird die Endzeit der letzten Verbindungsherstellung angegeben. Wenn eine persistente Verbindung verwendet wird, ist der Wert derselbe wie PerformanceTiming.fetchStart. Eine Verbindung gilt als geöffnet, wenn alle sicheren Verbindungs-Handshakes oder SOCKS-Authentifizierungen beendet sind.
[`connectStart`](/de/docs/Web/API/PerformanceTiming/connectStart) Wenn die Anfrage zum Öffnen einer Verbindung an das Netzwerk gesendet wird. Wenn die Transportschicht einen Fehler meldet und die Verbindung erneut gestartet wird, wird die Startzeit der letzten Verbindungsherstellung angegeben. Wenn eine persistente Verbindung verwendet wird, ist der Wert derselbe wie PerformanceTiming.fetchStart.
[`domainLookupEnd`](/de/docs/Web/API/PerformanceTiming/domainLookupEnd) Wenn die Domain-Abfrage abgeschlossen ist. Wenn eine persistente Verbindung verwendet wird oder die Information im Cache oder einer lokalen Ressource gespeichert ist, ist der Wert derselbe wie PerformanceTiming.fetchStart.
[`domainLookupStart`](/de/docs/Web/API/PerformanceTiming/domainLookupStart) Wenn die Domain-Abfrage beginnt. Wenn eine persistente Verbindung verwendet wird oder die Information im Cache oder einer lokalen Ressource gespeichert ist, ist der Wert derselbe wie PerformanceTiming.fetchStart.
[`fetchStart`](/de/docs/Web/API/PerformanceTiming/fetchStart) Wenn der Browser bereit ist, das Dokument mit einer HTTP-Anfrage abzurufen. Dieser Moment liegt vor der Überprüfung eines Anwendungs-Caches.
[`requestStart`](/de/docs/Web/API/PerformanceTiming/requestStart) Wenn der Browser die Anfrage gesendet hat, um das aktuelle Dokument vom Server oder aus einem Cache zu erhalten. Wenn die Transportschicht nach Beginn der Anfrage fehlschlägt und die Verbindung erneut geöffnet wird, wird diese Eigenschaft auf die Zeit der neuen Anfrage gesetzt.
[`responseStart`](/de/docs/Web/API/PerformanceTiming/responseStart) Wenn der Browser das erste Byte der Antwort vom Server, aus einem Cache oder einer lokalen Ressource empfangen hat.
[`responseEnd`](/de/docs/Web/API/PerformanceTiming/responseEnd) Wenn der Browser das letzte Byte der Antwort empfangen hat oder wenn die Verbindung geschlossen wird, falls dies zuerst geschah, vom Server, dem Cache oder einer lokalen Ressource.
[`domLoading`](/de/docs/Web/API/PerformanceTiming/domLoading) Wenn der Parser seine Arbeit begonnen hat, also wenn sein [`Document.readyState`](/de/docs/Web/API/Document/readyState) zu 'loading' wechselt und das entsprechende [`readystatechange`](/de/docs/Web/API/Document/readystatechange_event) Ereignis ausgelöst wird.
[`unloadEventStart`](/de/docs/Web/API/PerformanceTiming/unloadEventStart) Wenn das [`unload`](/de/docs/Web/API/Window/unload_event) Ereignis ausgelöst wurde, das die Zeit angibt, zu der das vorherige Dokument im Fenster mit dem Entladen begonnen hat. Wenn es kein vorheriges Dokument gibt oder wenn das vorherige Dokument oder einer der benötigten Weiterleitungen nicht vom selben Ursprung stammt, wird der Wert 0 zurückgegeben.
[`unloadEventEnd`](/de/docs/Web/API/PerformanceTiming/unloadEventEnd) Wenn der unload Ereignishandler abgeschlossen ist. Wenn es kein vorheriges Dokument gibt oder wenn das vorherige Dokument oder eine der benötigten Weiterleitungen nicht vom selben Ursprung stammt, wird der Wert 0 zurückgegeben.
[`domInteractive`](/de/docs/Web/API/PerformanceTiming/domInteractive) Wenn der Parser seine Arbeit am Hauptdokument beendet hat, also wenn sein Document.readyState zu 'interactive' wechselt und das entsprechende readystatechange Ereignis ausgelöst wird.
[`domContentLoadedEventStart`](/de/docs/Web/API/PerformanceTiming/domContentLoadedEventStart) Unmittelbar bevor der Parser das DOMContentLoaded Ereignis gesendet hat, das heißt direkt nachdem alle Skripte, die direkt nach dem Parsen ausgeführt werden müssen, ausgeführt wurden.
[`domContentLoadedEventEnd`](/de/docs/Web/API/PerformanceTiming/domContentLoadedEventEnd) Unmittelbar nachdem alle Skripte, die so schnell wie möglich in beliebiger Reihenfolge ausgeführt werden müssen, ausgeführt wurden.
[`domComplete`](/de/docs/Web/API/PerformanceTiming/domComplete) Wenn der Parser seine Arbeit am Hauptdokument beendet hat, also wenn sein Document.readyState zu 'complete' wechselt und das entsprechende readystatechange Ereignis ausgelöst wird.
[`loadEventStart`](/de/docs/Web/API/PerformanceTiming/loadEventStart) Wenn das load Ereignis für das aktuelle Dokument gesendet wurde. Wenn dieses Ereignis noch nicht gesendet wurde, wird 0 zurückgegeben.
[`loadEventEnd`](/de/docs/Web/API/PerformanceTiming/loadEventEnd) Wenn der load Ereignishandler beendet ist, das heißt, wenn das Ladeereignis abgeschlossen ist. Wenn dieses Ereignis noch nicht gesendet oder abgeschlossen ist, wird 0 zurückgegeben.

Berechnung von Zeiten

Wir können diese Werte verwenden, um spezifische, interessante Zeiten zu messen:

js
const dns = time.domainLookupEnd - time.domainLookupStart;
const tcp = time.connectEnd - time.connectStart;
const tls = time.requestStart - time.secureConnectionStart;

Time to First Byte

Time to First Byte ist die Zeit zwischen navigationStart (Beginn der Navigation) und responseStart (wenn das erste Byte der Antwortdaten empfangen wird), verfügbar in der performanceTiming API:

js
const ttfb = time.responseStart - time.navigationStart;

Seitenladezeit

Seitenladezeit ist die Zeit zwischen navigationStart und dem Beginn des Ladevorgangs des aktuellen Dokuments. Diese sind nur in der performanceTiming API verfügbar.

js
let pageloadTime = time.loadEventStart - time.navigationStart;

DNS-Abfragezeit

Die DNS-Abfragezeit ist die Zeit zwischen domainLookupStart und domainLookupEnd. Diese sind in beiden, der performanceTiming und der performanceNavigationTiming APIs, verfügbar.

js
const dns = time.domainLookupEnd - time.domainLookupStart;

TCP

Die Zeit, die für das TCP Handshake benötigt wird, ist die Zeit zwischen Verbindungsbeginn und Verbindungsende:

js
const tcp = time.connectEnd - time.connectStart;

TLS-Verhandlung

secureConnectionStart wird undefined, wenn nicht verfügbar, 0, wenn HTTPS nicht verwendet wird, oder ein Zeitstempel, wenn verfügbar und verwendet. Mit anderen Worten, wenn eine sichere Verbindung verwendet wurde, ist secureConnectionStart truthy, und die Zeit zwischen secureConnectionStart und requestStart wird größer als 0 sein.

js
const tls = time.requestStart - time.secureConnectionStart;

Performance Entry API

Die oben genannten allgemeinen Performance-Timings sind veraltet, aber vollständig unterstützt. Wir haben jetzt die Performance Entry API, die das Markieren und Messen von Zeiten entlang des Navigations- und Ressourcenladeprozesses ermöglicht. Sie können auch Markierungen erstellen:

js
performance.getEntriesByType("navigation").forEach((navigation) => {
  console.dir(navigation);
});

performance.getEntriesByType("resource").forEach((resource) => {
  console.dir(resource);
});

performance.getEntriesByType("mark").forEach((mark) => {
  console.dir(mark);
});

performance.getEntriesByType("measure").forEach((measure) => {
  console.dir(measure);
});

performance.getEntriesByType("paint").forEach((paint) => {
  console.dir(paint);
});

performance.getEntriesByType("frame").forEach((frame) => {
  console.dir(frame);
});

In unterstützenden Browsern können Sie performance.getEntriesByType('paint') verwenden, um das Maß für first-paint und first-contentful-paint abzufragen. Wir verwenden performance.getEntriesByType('navigation') und performance.getEntriesByType('resource'), um die Navigations- und Ressourcen-Zeiten abzufragen.

Wenn ein Nutzer eine Website oder Anwendung anfordert, durchläuft der Nutzeragent eine Reihe von Schritten, darunter eine DNS-Abfrage, TCP-Handshakes und TLS-Verhandlung, bevor der Nutzeragent die eigentliche Anfrage stellt und die Server die angeforderten Assets zurücksenden. Der Browser parst dann die empfangenen Inhalte, baut den DOM, CSSOM, Zugänglichkeit und Render-Bäume auf und rendert schließlich die Seite. Sobald der Nutzeragent das Parsen des Dokuments beendet hat, setzt der Nutzeragent die Dokumentbereitschaft auf interaktiv. Wenn es verzögerte Skripte gibt, die geparst werden müssen, wird er es tun, dann das DOMContentLoaded auslösen, danach wird die Bereitschaft auf vollständig gesetzt. Das Dokument kann nun nachgelagerte Aufgaben bearbeiten, nach denen das Dokument als vollständig geladen markiert wird.

js
const navigationTimings = performance.getEntriesByType("navigation");

Das performance.getEntriesByType('navigation') gibt ein Array von PerformanceEntry Objekten für den navigation type zurück.

Die Ergebnisse, wenn performance.getEntriesByType('navigation'); in die Konsole für dieses Dokument eingegeben wird.

Vieles kann aus diesen Timings gewonnen werden. Im obigen Bild sehen wir über die name Eigenschaft, dass die Datei, die gemessen wird, dieses Dokument ist. Für die weitere Erklärung verwenden wir die folgende Variable:

js
const timing = performance.getEntriesByType("navigation")[0];

Protokoll

Wir können das verwendete Protokoll durch Abfrage überprüfen:

js
const protocol = timing.nextHopProtocol;

Es gibt das Netzwerkprotokoll zurück, das verwendet wurde, um die Ressource abzurufen: in diesem Fall h2 für http/2.

Komprimierung

Um die Einsparungsprozentsätze bei der Komprimierung zu erhalten, teilen wir die transferSize durch die decodedBodySize und subtrahieren das von 100%. Wir sehen eine Einsparung von über 74%.

js
const compressionSavings = 1 - timing.transferSize / timing.decodedBodySize;

Wir hätten

js
const compressionSavings = 1 - timing.encodedBodySize / timing.decodedBodySize;

verwenden können, aber die Verwendung von transferSize schließt die Overhead-Bytes ein.

Zum Vergleich können wir auf den Netzwerk-Tab schauen und sehen, dass wir 22,04 KB für eine unkomprimierte Dateigröße von 87,24 KB transferiert haben.

Ansicht der übertragenen Bytes und der Größe über den Netzwerk-Tab

Wenn wir die Mathematik mit diesen Zahlen durchführen, erhalten wir dasselbe Ergebnis: 1 - (22,04 / 87,24) = 0,747. Die Navigationstiming ermöglicht es uns, programmgesteuert Transfergrößen und Bandbreiteneinsparungen zu überprüfen.

Beachten Sie, dass dies die Größe für dieses einzelne Dokument allein ist: für diese Ressource allein, nicht für alle Ressourcen zusammen. Die Dauer, Ladeereignisse und DOM-bezogene Timings beziehen sich jedoch auf die gesamte Navigation, nicht auf dieses einzelne Asset. Client-seitige Webanwendungen können schneller erscheinen als diese mit Transfergrößen unter 10000 und dekodierten Körpergrößen unter 30000, aber das bedeutet nicht, dass JavaScript, CSS oder Medien-Assets keinen Ballast hinzufügen. Das Überprüfen von Kompressionsverhältnissen ist wichtig, aber stellen Sie sicher, dass Sie auch die Dauer und die Zeit zwischen dem Ende des DOMContentLoaded-Events und dem vollständigen DOM überprüfen, da das Ausführen von JavaScript im Hauptthread über lange Zeiträume zu einer nicht antwortenden Benutzeroberfläche führen kann.

Anfragetime

Die API liefert nicht jede Messung, die Sie möglicherweise wünschen. Zum Beispiel, wie lange hat die Anfrage gedauert? Wir können die Messungen, die wir haben, verwenden, um unsere Antwort zu bekommen.

Um die Antwortzeit zu messen, ziehen Sie die Startzeit der Anforderung von der Startzeit der Antwort ab. Der Anfragebeginn ist der Moment unmittelbar bevor der Nutzeragent die Ressource vom Server, den relevanten Anwendungs-Caches oder den lokalen Ressourcen anfordert. Die Antwortbeginn ist die Zeit unmittelbar nachdem der HTTP-Parser des Nutzeragenten das erste Byte der Antwort von den relevanten Anwendungs-Caches, den lokalen Ressourcen oder dem Server erhält, was geschieht, nachdem die Anfrage empfangen und verarbeitet wurde.

js
const request = timing.responseStart - timing.requestStart;

Ladeereignisdauer

Indem Sie den Zeitstempel von unmittelbar bevor das Ladeereignis des aktuellen Dokuments ausgelöst wird von der Zeit subtrahieren, zu der das Ladeereignis des aktuellen Dokuments abgeschlossen ist, können Sie die Dauer des Ladeereignisses messen.

js
const load = timing.loadEventEnd - timing.loadEventStart;

DOMContentLoaded-Ereignis

Die Dauer des DOMContentLoaded-Ereignisses wird gemessen, indem der Zeitwert unmittelbar bevor der Nutzeragent das DOMContentLoaded-Ereignis auslöst von dem Zeitwert unmittelbar nach Abschluss des Ereignisses subtrahiert wird. Dieses Ereignis auf 50 ms oder schneller zu halten, trägt dazu bei, eine ansprechende Benutzeroberfläche sicherzustellen.

js
const DOMContentLoaded =
  timing.domContentLoadedEventEnd - timing.domContentLoadedEventStart;

Dauer

Wir erhalten die Dauer. Die Dauer ist der Unterschied zwischen den Eigenschaften PerformanceNavigationTiming.loadEventEnd und PerformanceEntry.startTime.

Die PerformanceNavigationTiming-Schnittstelle bietet zudem Informationen darüber, welche Navigationsart Sie messen, indem sie navigate, reload oder back_forward zurückgibt.

Ressourcen-Timing

Während das Navigations-Timing zur Messung der Leistung der Hauptseite dient, in der Regel die HTML-Datei, über die alle anderen Assets angefordert werden, misst das Ressourcen-Timing die Zeiten für einzelne Ressourcen, die vom Hauptdokument aufgerufenen Assets und alle Ressourcen, die diese Ressourcen anfordern. Viele der Messungen sind ähnlich: Es gibt eine DNS-Abfrage, ein TCP-Handshake und der Beginn der sicheren Verbindung wird einmal pro Domäne durchgeführt.

Grafik der Resource Timing Zeitstempel

Das Hauptaugenmerk liegt auf den einzelnen Ressourcen.

Siehe auch