Start · Sprachen · JavaScript · Referenz · Performance

Performance

Schnittstelle

Das <code>Performance</code>-Interface bietet Zugriff auf hochauflösende Zeitmessung und leistungsbezogene Informationen (Timeline-Einträge) der aktuellen Seite oder des Workers.

seit JavaScript Baseline: alle Browser (High Resolution Time Level Kategorie: webapi

Signatur

interface Performance extends EventTarget

Beschreibung

Das Performance-Interface ist der zentrale Einstiegspunkt der Performance-APIs. Es gibt keine eigene Instanziierung: Man greift über das globale Objekt performance (bzw. window.performance oder self.performance im Worker) darauf zu. Grundlage ist eine monoton steigende, hochauflösende Uhr, deren Nullpunkt performance.timeOrigin ist – also der Beginn der Navigation bzw. der Start des Workers.

Wichtige Mitglieder sind:

  • performance.now() – aktuelle Zeit in Millisekunden (Gleitkommazahl) relativ zu timeOrigin, ideal für Messungen, da nicht von Systemuhr-Änderungen betroffen.
  • performance.mark(name) und performance.measure(name, start, end) – eigene Zeitpunkte und Zeitspannen setzen (User Timing API).
  • performance.getEntries(), getEntriesByType(type), getEntriesByName(name) – Zugriff auf die Performance-Timeline (z. B. "navigation", "resource", "mark", "measure", "paint").
  • clearMarks(), clearMeasures(), clearResourceTimings(), setResourceTimingBufferSize() – Pufferverwaltung.
  • performance.timeOrigin und performance.toJSON() – Zeitbasis und serialisierbare Darstellung.
  • Event resourcetimingbufferfull – wird ausgelöst, wenn der Resource-Timing-Puffer voll ist.

Einsatzgebiete sind Benchmarks einzelner Funktionen, das Messen von Ladezeiten (Navigation Timing, Resource Timing), das Erfassen von Metriken für Real User Monitoring (RUM) sowie das Sichtbarmachen eigener Abschnitte im Performance-Panel der Browser-Entwicklerwerkzeuge über mark()/measure(). Für das fortlaufende Beobachten neuer Einträge sollte man PerformanceObserver statt wiederholtem Polling von getEntries() verwenden.

Rückgabewert

Typ
Performance
Beschreibung
Das globale Objekt performance ist die einzige Instanz; es kann nicht per new Performance() erzeugt werden.

Beispiele

Laufzeit einer Funktion mit performance.now() messen

const fib = (n) => (n < 2 ? n : fib(n - 1) + fib(n - 2));

const start = performance.now();
const result = fib(27);
const dauer = performance.now() - start;

console.log(`fib(27) = ${result}, Dauer: ${dauer.toFixed(2)} ms`);
fib(27) = 196418, Dauer: 4.30 ms (Wert variiert)

Eigene Abschnitte mit mark() und measure() erfassen

const ladeDaten = async () => {
  performance.mark('daten-start');
  const res = await fetch('https://jsonplaceholder.typicode.com/todos');
  const todos = await res.json();
  performance.mark('daten-ende');

  const messung = performance.measure('daten-laden', 'daten-start', 'daten-ende');
  console.log(`${todos.length} Einträge in ${messung.duration.toFixed(1)} ms geladen`);

  // Aufräumen, damit der Puffer nicht wächst
  performance.clearMarks();
  performance.clearMeasures();
};

ladeDaten();
200 Einträge in 142.7 ms geladen (Wert variiert)

Navigation- und Resource-Timing auswerten

window.addEventListener('load', () => {
  const [nav] = performance.getEntriesByType('navigation');
  console.log('TTFB:', Math.round(nav.responseStart - nav.requestStart), 'ms');
  console.log('DOMContentLoaded:', Math.round(nav.domContentLoadedEventEnd), 'ms');

  const langsam = performance
    .getEntriesByType('resource')
    .filter((r) => r.duration > 200)
    .map((r) => ({ url: r.name, ms: Math.round(r.duration) }));
  console.table(langsam);
});
TTFB: 85 ms DOMContentLoaded: 412 ms (Tabelle langsamer Ressourcen)

Neue Einträge mit PerformanceObserver beobachten und Puffer überwachen

const observer = new PerformanceObserver((liste) => {
  for (const eintrag of liste.getEntries()) {
    console.log(`${eintrag.entryType}: ${eintrag.name} – ${eintrag.startTime.toFixed(0)} ms`);
  }
});
observer.observe({ type: 'paint', buffered: true });

performance.setResourceTimingBufferSize(300);
performance.addEventListener('resourcetimingbufferfull', () => {
  console.warn('Resource-Timing-Puffer voll – wird geleert');
  performance.clearResourceTimings();
});
paint: first-paint – 180 ms paint: first-contentful-paint – 180 ms

// Wichtig · Fallstricke

  • Genauigkeit reduziert: Zum Schutz vor Timing-Angriffen (Spectre) runden Browser performance.now() ab (z. B. 100 µs in Chrome, in Firefox teils 1 ms oder gröber mit privacy.resistFingerprinting). Höhere Auflösung gibt es nur in cross-origin-isolierten Kontexten (COOP/COEP-Header, crossOriginIsolated === true).
  • performance.now() statt Date.now(): Date.now() kann durch Systemuhr-Anpassungen springen; performance.now() ist monoton. Für absolute Zeitstempel performance.timeOrigin + performance.now() verwenden.
  • Veraltet: performance.timing (PerformanceTiming) und performance.navigation sind deprecated – stattdessen getEntriesByType('navigation') (PerformanceNavigationTiming) nutzen. performance.memory ist nicht standardisiert (nur Chromium).
  • Cross-Origin-Ressourcen: Detaillierte Resource-Timing-Werte (z. B. requestStart, transferSize) sind für fremde Origins 0, sofern der Server nicht den Header Timing-Allow-Origin sendet.
  • Puffergrößen: Der Resource-Timing-Puffer ist standardmäßig auf 250 Einträge begrenzt; Marks/Measures wachsen unbegrenzt und sollten in langlebigen Single-Page-Apps regelmäßig mit clearMarks()/clearMeasures() geleert werden.
  • Zeitbasis in Workern: Jeder Worker hat eine eigene timeOrigin; Werte aus Worker und Hauptthread sind nur über timeOrigin vergleichbar.
  • In Node.js steht performance ab Version 16 global zur Verfügung (vorher über require('node:perf_hooks')).