Start · Sprachen · JavaScript · Referenz · PerformanceServerTiming

PerformanceServerTiming

Schnittstelle

Das Interface <code>PerformanceServerTiming</code> stellt Servermetriken bereit, die der Server mit der Antwort im HTTP-Header <code>Server-Timing</code> sendet.

seit JavaScript Baseline 2023: Chrome 65+, Firefox 61+, Safari 16. Kategorie: webapi

Signatur

interface PerformanceServerTiming

Beschreibung

Mit PerformanceServerTiming kann der Browser Messwerte auslesen, die der Server über den HTTP-Header Server-Timing mitschickt, zum Beispiel die Dauer von Datenbankabfragen, Cache-Treffer oder die Renderzeit einer Vorlage. So lassen sich Frontend- und Backend-Leistung in einer einzigen Real-User-Monitoring-Auswertung (RUM) zusammenführen.

Instanzen erzeugt man nicht selbst. Man erhält sie über die Eigenschaft serverTiming eines PerformanceResourceTiming-Eintrags oder eines PerformanceNavigationTiming-Eintrags. Jeder Eintrag im Header wird zu genau einem PerformanceServerTiming-Objekt.

Das Interface ist schreibgeschützt und hat folgende Eigenschaften:

  • name (string): Name der Metrik, z. B. db
  • duration (number): Dauer in Millisekunden aus dem Parameter dur, sonst 0
  • description (string): Beschreibung aus dem Parameter desc, sonst ein leerer String
  • toJSON(): gibt eine JSON-taugliche Darstellung des Objekts zurück

Ein Header wie Server-Timing: db;dur=53;desc="Datenbank", cache;desc="HIT", app;dur=47.2 ergibt drei Einträge.

Rückgabewert

Typ
PerformanceServerTiming
Beschreibung
Wird nicht direkt erzeugt, sondern als Element des Arrays PerformanceResourceTiming.serverTiming geliefert (Typ ReadonlyArray<PerformanceServerTiming>).

Beispiele

Server-Timing der aktuellen Seite auslesen

// Server-Header: Server-Timing: db;dur=53;desc="Datenbank", app;dur=47.2
const [navigation] = performance.getEntriesByType('navigation');

for (const { name, duration, description } of navigation?.serverTiming ?? []) {
  console.log(`${name}: ${duration} ms (${description || 'ohne Beschreibung'})`);
}
db: 53 ms (Datenbank) app: 47.2 ms (ohne Beschreibung)

Metriken von fetch-Anfragen mit PerformanceObserver überwachen

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.serverTiming?.length) continue;
    const metrics = entry.serverTiming.map((t) => t.toJSON());
    console.log(new URL(entry.name).pathname, metrics);
  }
});

observer.observe({ type: 'resource', buffered: true });

await fetch('/api/produkte');
/api/produkte [ { name: 'db', duration: 12.4, description: 'Abfrage' } ]

Servermetriken an ein Monitoring-Backend senden

const sendServerTimings = () => {
  const payload = performance
    .getEntriesByType('resource')
    .filter((e) => e.serverTiming.length > 0)
    .map((e) => ({
      url: e.name,
      metriken: Object.fromEntries(
        e.serverTiming.map((t) => [t.name, t.duration])
      )
    }));

  if (payload.length) {
    navigator.sendBeacon('/rum', JSON.stringify(payload));
  }
};

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') sendServerTimings();
});

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: Über HTTP ohne TLS bleibt serverTiming ein leeres Array (Safari hat das erst ab Version 16.4 unterstützt).
  • Cross-Origin: Bei Ressourcen von fremden Origins sind die Werte nur sichtbar, wenn der Server Timing-Allow-Origin sendet, z. B. Timing-Allow-Origin: https://example.com. Fehlt der Header, ist das Array leer.
  • Sicherheit: Die Werte sind für jedes Skript auf der Seite und in den DevTools sichtbar. Keine internen Details wie Hostnamen, SQL-Abfragen oder Benutzerdaten in desc senden. Genaue Zeitangaben können außerdem Timing-Angriffe erleichtern, deshalb in der Produktion eher runden oder nur für eingeloggte Admins senden.
  • duration ist 0, wenn dur fehlt. 0 heißt also nicht unbedingt „keine Zeit gebraucht“.
  • Der Header kann auch als HTTP-Trailer gesendet werden, das unterstützen Browser bisher aber kaum.
  • Auch in Web Workern verfügbar.