Start · Sprachen · JavaScript · Referenz · PerformanceResourceTiming.serverTiming

PerformanceResourceTiming.serverTiming

Eigenschaft

Schreibgeschützte Eigenschaft, die ein Array von <code>PerformanceServerTiming</code>-Einträgen mit den Metriken aus dem HTTP-Header <code>Server-Timing</code> liefert.

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

Signatur

PerformanceResourceTiming.serverTiming

Beschreibung

Über serverTiming kommen serverseitige Messwerte im Browser an. Der Server schickt dafür den HTTP-Antwort-Header Server-Timing mit, z. B. Server-Timing: db;dur=53;desc="Datenbank", cache;desc="HIT". Der Browser zerlegt diesen Header und stellt jeden Eintrag als PerformanceServerTiming-Objekt mit den Eigenschaften name, duration und description bereit.

Die Eigenschaft gibt es bei PerformanceResourceTiming-Einträgen (Bilder, Skripte, fetch-Aufrufe usw.) und bei PerformanceNavigationTiming, das von PerformanceResourceTiming erbt. Dort enthält sie die Metriken des HTML-Dokuments selbst. So lassen sich Backend-Zeiten wie Datenbankabfragen, Template-Rendering oder Cache-Treffer direkt im Real User Monitoring (RUM) zusammen mit den Frontend-Timings erfassen.

Hat die Antwort keinen Server-Timing-Header oder dürfen die Daten nicht offengelegt werden (siehe Hinweise zu CORS), ist das Array leer. Das Array ist ein unveränderlicher Schnappschuss. Wenn Sie es ändern, hat das keine Auswirkung auf den Performance-Eintrag.

Rückgabewert

Typ
PerformanceServerTiming[]
Beschreibung
Ein Array von PerformanceServerTiming-Objekten mit name (string), duration (number, Millisekunden, Standardwert 0) und description (string, Standardwert ""). Ohne Header oder bei gesperrtem Zugriff ist das Array leer.

Beispiele

Server-Metriken der aktuellen Seite auslesen

// Antwort-Header des Servers:
// Server-Timing: db;dur=53.2;desc="Datenbank", render;dur=18, cache;desc="HIT"
const [navigation] = performance.getEntriesByType('navigation');

for (const { name, duration, description } of navigation.serverTiming) {
  console.log(`${name}: ${duration} ms (${description})`);
}
db: 53.2 ms (Datenbank) render: 18 ms () cache: 0 ms (HIT)

Server-Timing aller fetch-Aufrufe laufend beobachten

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.initiatorType !== 'fetch') continue;
    const metrics = Object.fromEntries(
      entry.serverTiming.map((m) => [m.name, m.duration])
    );
    console.log(new URL(entry.name).pathname, metrics);
  }
});

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

await fetch('/api/produkte');
/api/produkte { db: 41.7, app: 12.3 }

Metriken an einen RUM-Endpunkt senden

window.addEventListener('pagehide', () => {
  const [nav] = performance.getEntriesByType('navigation');
  const payload = {
    url: location.pathname,
    ttfb: nav.responseStart - nav.requestStart,
    server: nav.serverTiming.map(({ name, duration, description }) => ({
      name, duration, description
    }))
  };
  navigator.sendBeacon('/rum', JSON.stringify(payload));
});

Server-Timing-Header in Node.js setzen

import http from 'node:http';

http.createServer(async (req, res) => {
  const start = performance.now();
  const daten = await new Promise((r) => setTimeout(() => r('[]'), 30)); // simulierte DB
  const dbDauer = (performance.now() - start).toFixed(1);

  res.setHeader('Server-Timing', `db;dur=${dbDauer};desc="Datenbank"`);
  res.setHeader('Timing-Allow-Origin', 'https://www.example.com');
  res.setHeader('Content-Type', 'application/json');
  res.end(daten);
}).listen(3000);

// Wichtig · Fallstricke

  • Cross-Origin: Bei Ressourcen von fremden Ursprüngen ist serverTiming leer. Das ändert sich nur, wenn der Server den Header Timing-Allow-Origin passend setzt (z. B. Timing-Allow-Origin: * oder den konkreten Ursprung). Access-Control-Allow-Origin reicht dafür nicht aus.
  • Nur sichere Kontexte: Die Daten stehen nur über HTTPS (bzw. localhost) zur Verfügung.
  • Datenschutz und Sicherheit: Die Metriken kann jeder Seitenbesucher lesen. Schicken Sie keine internen Hostnamen, SQL-Abfragen, Versionsnummern oder Nutzerdaten im Header mit. Sehr genaue Zeitangaben können außerdem Timing-Angriffe erleichtern. Geben Sie den Header deshalb eher gerundet oder nur in bestimmten Umgebungen aus.
  • Zwischengespeicherte Antworten: Kommt eine Ressource aus dem HTTP-Cache, enthält serverTiming unter Umständen die alten Werte aus der gespeicherten Antwort. Diese Werte stammen nicht aus der aktuellen Anfrage.
  • Parsing: Fehlt dur, ist duration gleich 0. Ungültig formatierte Einträge werden stillschweigend übergangen. Metriken mit gleichem Namen bleiben alle erhalten.
  • Kompatibilität: Safari unterstützt die Eigenschaft erst ab Version 16.4. Prüfen Sie ältere Browser vorher mit 'serverTiming' in PerformanceResourceTiming.prototype.
  • Die Metriken erscheinen auch in den Browser-Entwicklertools (Netzwerk → Timing) und helfen so beim Debuggen.