Messen der Leistung mit Server-Timing

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Der Server-Timing-Header bietet eine diskrete und bequeme Möglichkeit, Backend-Server-Performance-Timings an Entwicklertools im Browser zu übermitteln. Durch das Hinzufügen von Timing-Informationen zu Ihrer Anwendung können Sie die Back-End- und Front-End-Leistung an einem Ort überwachen.

Wenn wir irgendeine Art von Arbeit zur Leistungsoptimierung durchführen, lernen wir als Erstes, dass Sie die Leistung zuerst messen müssen, bevor Sie sie verbessern können. Ohne die Geschwindigkeit messen zu können, mit der etwas funktioniert, können wir nicht sagen, ob die vorgenommenen Änderungen die Leistung verbessern, keine Auswirkungen haben oder die Dinge sogar verschlimmern.

Viele von uns werden mit der Arbeit an Leistungsproblemen auf einer bestimmten Ebene vertraut sein. Das kann etwas so Einfaches sein wie der Versuch, herauszufinden, warum JavaScript auf Ihrer Seite nicht früh genug einsetzt oder warum es zu lange dauert, bis Bilder in schlechtem Hotel-WLAN erscheinen. Die Antwort auf diese Art von Fragen finden Sie oft an einem sehr vertrauten Ort: den Entwicklertools Ihres Browsers.

Im Laufe der Jahre wurden die Entwicklertools verbessert, um uns bei der Behebung dieser Art von Leistungsproblemen im Front-End unserer Anwendungen zu unterstützen. Browser haben jetzt sogar Leistungsprüfungen direkt integriert. Dies kann helfen, Frontend-Probleme aufzuspüren, aber diese Prüfungen können eine andere Quelle der Langsamkeit aufzeigen, die wir im Browser nicht beheben können. Dieses Problem sind langsame Serverantwortzeiten.

„Zeit bis zum ersten Byte“

Es gibt sehr wenig Browseroptimierungen, um eine Seite zu verbessern, die einfach nur langsam auf dem Server erstellt wird. Diese Kosten entstehen zwischen der Anforderung der Datei durch den Browser und dem Empfang der Antwort. Wenn Sie Ihr Netzwerk-Wasserfalldiagramm in den Entwicklertools studieren, wird diese Verzögerung unter der Kategorie „Wartend (TTFB)“ angezeigt. So lange wartet der Browser zwischen der Anfrage und dem Erhalt der Antwort.

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

In Bezug auf die Leistung ist dies als Zeit bis zum ersten Byte bekannt - die Zeit, die es dauert, bis der Server beginnt, etwas zu senden, mit dem der Browser arbeiten kann. In dieser Wartezeit ist alles enthalten, was der Server tun muss, um die Seite zu erstellen. Bei einer typischen Website kann dies das Weiterleiten der Anforderung an den richtigen Teil der Anwendung, das Authentifizieren der Anforderung, das Ausführen mehrerer Aufrufe an Backend-Systeme wie Datenbanken usw. umfassen. Es könnte das Ausführen von Inhalten durch Templating-Systeme, API-Aufrufe an Drittanbieterdienste und vielleicht sogar Dinge wie das Versenden von E-Mails oder das Ändern der Bildgröße beinhalten. Jegliche Arbeit, die der Server zum Abschließen einer Anfrage leistet, wird in diese TTFB-Wartezeit gequetscht, die der Benutzer in seinem Browser erlebt.

Das Netzwerk-Panel in Chrome DevTools, das die Überprüfung einer einzelnen Seitenanforderung zeigt
Die Untersuchung einer Dokumentanforderung zeigt die Zeit, die der Browser damit verbringt, auf die Antwort vom Server zu warten.

Wie können wir also diese Zeit verkürzen und die Seite schneller für den Benutzer bereitstellen? Nun, das ist eine große Frage, und die Antwort hängt von Ihrer Anwendung ab. Das ist die Arbeit der Leistungsoptimierung selbst. Was wir zuerst tun müssen, ist die Leistung zu messen , damit der Nutzen von Änderungen beurteilt werden kann.

Der Server-Timing-Header

Die Aufgabe des Server-Timings besteht nicht darin, Ihnen dabei zu helfen, die Aktivitäten auf Ihrem Server tatsächlich zu timen. Sie müssen das Timing selbst vornehmen, indem Sie das Toolset verwenden, das Ihre Backend-Plattform Ihnen zur Verfügung stellt. Der Zweck des Server-Timings besteht vielmehr darin, anzugeben, wie diese Messungen an den Browser übermittelt werden können.

Die Art und Weise, wie dies geschieht, ist sehr einfach, für den Benutzer transparent und hat nur minimale Auswirkungen auf das Gewicht Ihrer Seite. Die Informationen werden als einfacher Satz von HTTP-Antwortheadern gesendet.

 Server-Timing: db;dur=123, tmpl;dur=56

Dieses Beispiel kommuniziert zwei verschiedene Zeitpunkte mit den Namen db und tmpl . Diese sind nicht Teil der Spezifikation - dies sind Namen, die wir ausgewählt haben, in diesem Fall, um einige Datenbank- bzw. Vorlagen-Timings darzustellen.

Die Eigenschaft dur gibt die Anzahl der Millisekunden an, die der Vorgang zum Abschluss benötigt hat. Wenn wir uns die Anfrage im Abschnitt "Netzwerk" der Entwicklertools ansehen, können wir sehen, dass die Zeitangaben zum Diagramm hinzugefügt wurden.

Der Bereich „Timings“ einer Seitenanforderung in Chrome DevTools mit einem neuen Abschnitt „Server-Timing“.
Ein neuer Abschnitt „Server-Timing“ wird angezeigt, in dem die mit dem Server-Timing-HTTP-Header festgelegten Timings angezeigt werden.

Der Server-Timing Header kann mehrere durch Kommas getrennte Metriken annehmen:

 Server-Timing: metric, metric, metric

Jede Metrik kann drei mögliche Eigenschaften angeben

  1. Ein Kurzname für die Metrik (z. B. db in unserem Beispiel)
  2. Eine Dauer in Millisekunden (ausgedrückt als dur=123 )
  3. Eine Beschreibung (ausgedrückt als desc="My Description" )

Jede Eigenschaft wird durch ein Semikolon als Trennzeichen getrennt. Wir könnten unserem Beispiel Beschreibungen wie folgt hinzufügen:

 Server-Timing: db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing"
Der Bereich „Timings“ einer Seitenanforderung in Chrome DevTools mit Beschreibungen, die für Server-Timing-Metriken verwendet werden.
Die Namen werden, sofern vorhanden, durch Beschreibungen ersetzt.

Die einzige erforderliche Eigenschaft ist name . Sowohl dur als desc sind optional und können bei Bedarf optional verwendet werden. Wenn Sie beispielsweise ein Timing-Problem debuggen müssen, das auf einem Server oder Rechenzentrum aufgetreten ist und nicht auf einem anderen, kann es hilfreich sein, diese Informationen ohne zugeordnetes Timing in die Antwort aufzunehmen.

 Server-Timing: datacenter;desc="East coast data center", db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing”

Dies würde dann zusammen mit den Timings angezeigt werden.

Der Bereich „Timings“ einer Seitenanforderung in Chrome DevTools zeigt ein Server-Timing ohne festgelegte Zeit.
Der Wert „Ostküsten-Rechenzentrum“ wird angezeigt, obwohl er keine Zeitangaben hat.

Eine Sache, die Ihnen vielleicht auffallen wird, ist, dass die Timing-Balken nicht in einem Wasserfallmuster angezeigt werden. Dies liegt einfach daran, dass Server Timing nicht versucht, die Abfolge von Timings zu kommunizieren, sondern nur die Rohmetriken selbst.

Implementieren von Server-Timing

Die genaue Implementierung in Ihrer eigenen Anwendung hängt von Ihren spezifischen Umständen ab, aber die Prinzipien sind die gleichen. Die Schritte werden immer sein:

  1. Zeit einige Operationen
  2. Sammeln Sie die Timing-Ergebnisse
  3. Geben Sie den HTTP-Header aus

In Pseudocode könnte die Generierung der Antwort so aussehen:

 startTimer('db') getInfoFromDatabase() stopTimer('db') startTimer('geo') geolocatePostalAddressWithAPI('10 Downing Street, London, UK') endTimer('geo') outputHeader('Server-Timing', getTimerOutput())

Die Grundlagen der Implementierung von etwas in dieser Richtung sollten in jeder Sprache einfach sein. Eine sehr einfache PHP-Implementierung könnte die microtime() Funktion für Timing-Operationen verwenden und in etwa so aussehen wie im Folgenden.

 class Timers { private $timers = []; public function startTimer($name, $description = null) { $this->timers[$name] = [ 'start' => microtime(true), 'desc' => $description, ]; } public function endTimer($name) { $this->timers[$name]['end'] = microtime(true); } public function getTimers() { $metrics = []; if (count($this->timers)) { foreach($this->timers as $name => $timer) { $timeTaken = ($timer['end'] - $timer['start']) * 1000; $output = sprintf('%s;dur=%f', $name, $timeTaken); if ($timer['desc'] != null) { $output .= sprintf(';desc="%s"', addslashes($timer['desc'])); } $metrics[] = $output; } } return implode($metrics, ', '); } }

Ein Testskript würde es wie unten verwenden, hier mit der Funktion usleep() , um künstlich eine Verzögerung bei der Ausführung des Skripts zu erzeugen, um einen Prozess zu simulieren, der Zeit braucht, um abgeschlossen zu werden.

 $Timers = new Timers(); $Timers->startTimer('db'); usleep('200000'); $Timers->endTimer('db'); $Timers->startTimer('tpl', 'Templating'); usleep('300000'); $Timers->endTimer('tpl'); $Timers->startTimer('geo', 'Geocoding'); usleep('400000'); $Timers->endTimer('geo'); header('Server-Timing: '.$Timers->getTimers());

Das Ausführen dieses Codes generierte einen Header, der so aussah:

 Server-Timing: db;dur=201.098919, tpl;dur=301.271915;desc="Templating", geo;dur=404.520988;desc="Geocoding"
Das Timings-Panel einer Seitenanforderung in Chrome DevTools zeigt die korrekt angezeigten Testwerte.
Die im Beispiel festgelegten Server-Timings werden im Timings-Bedienfeld mit den in unserem Testskript konfigurierten Verzögerungen angezeigt.

Bestehende Implementierungen

Wenn man bedenkt, wie praktisch Server-Timing ist, gibt es relativ wenige Implementierungen, die ich finden konnte. Das Server-Timing-NPM-Paket bietet eine bequeme Möglichkeit, das Server-Timing aus Node-Projekten zu verwenden.

Wenn Sie ein Middleware-basiertes PHP-Framework verwenden, bietet tuupola/server-timing-middleware ebenfalls eine praktische Option. Ich benutze das seit einigen Monaten in der Produktion auf Notist und lasse immer ein paar grundlegende Timings aktiviert, wenn Sie ein Beispiel in freier Wildbahn sehen möchten.

Was die Browserunterstützung betrifft, habe ich am besten in Chrome DevTools gesehen, und das habe ich für die Screenshots in diesem Artikel verwendet.

Überlegungen

Das Server-Timing selbst fügt der HTTP-Antwort, die über die Leitung zurückgesendet wird, nur einen sehr geringen Overhead hinzu. Der Header ist sehr minimal und kann im Allgemeinen sicher gesendet werden, ohne sich Gedanken über die Ausrichtung auf nur interne Benutzer machen zu müssen. Trotzdem lohnt es sich, Namen und Beschreibungen kurz zu halten, damit Sie keinen unnötigen Overhead hinzufügen.

Besorgniserregender ist die zusätzliche Arbeit, die Sie möglicherweise auf dem Server leisten, um Ihre Seite oder Anwendung zu timen. Das Hinzufügen von zusätzlichem Timing und Protokollierung kann sich selbst auf die Leistung auswirken, daher lohnt es sich, eine Möglichkeit zu implementieren, dies bei Bedarf ein- und auszuschalten.

Die Verwendung eines Server-Timing-Headers ist eine großartige Möglichkeit, um sicherzustellen, dass alle Timing-Informationen sowohl vom Front-End als auch vom Back-End Ihrer Anwendung an einem Ort zugänglich sind. Sofern Ihre Anwendung nicht zu komplex ist, lässt sie sich leicht implementieren und ist innerhalb kürzester Zeit einsatzbereit.

Wenn Sie mehr über Server-Timing erfahren möchten, können Sie Folgendes versuchen:

  • Die W3C-Server-Timing-Spezifikation
  • Die MDN-Seite zum Server-Timing enthält Beispiele und aktuelle Details zur Browserunterstützung
  • Ein interessanter Artikel des BBC iPlayer-Teams über die Verwendung von Server-Timing.