Start · Sprachen · JavaScript · Referenz · Performance.now()

Performance.now()

Methode

Gibt einen hochauflösenden Zeitstempel (<code>DOMHighResTimeStamp</code>) in Millisekunden relativ zum Zeitursprung der Seite bzw. des Workers zurück.

seit JavaScript Baseline: alle Browser (seit 2015); Node.js 8.5+ ( Kategorie: webapi

Signatur

Performance.prototype.now()

Beschreibung

performance.now() liefert die seit dem Zeitursprung (performance.timeOrigin) vergangene Zeit in Millisekunden als Gleitkommazahl. Der Zeitursprung ist in Fenstern typischerweise der Beginn der Navigation, in Workern der Zeitpunkt, an dem der Worker erzeugt wurde.

Im Gegensatz zu Date.now() ist der Wert monoton: Er wird nicht durch Änderungen der Systemuhr, NTP-Synchronisation oder Zeitzonenwechsel beeinflusst und kann nie rückwärts laufen. Außerdem enthält er Nachkommastellen (Sub-Millisekunden-Auflösung). Damit eignet sich die Methode ideal zum Messen von Zeitdauern: Laufzeit von Funktionen, Benchmarks, Frame-Zeiten in Animationen oder Latenz von Netzwerkanfragen.

Für echte Uhrzeiten (z. B. „wann ist etwas passiert“) ist performance.now() ungeeignet – dafür nimmt man Date.now() oder rechnet performance.timeOrigin + performance.now(). Für benannte Messpunkte, die in DevTools auftauchen, bieten sich performance.mark() und performance.measure() an.

Rückgabewert

Typ
number (DOMHighResTimeStamp)
Beschreibung
Vergangene Zeit seit performance.timeOrigin in Millisekunden, als Gleitkommazahl mit begrenzter (absichtlich gerundeter) Genauigkeit.

Beispiele

Laufzeit einer Funktion 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} in ${dauer.toFixed(2)} ms`);
fib(27) = 196418 in 4.30 ms (Wert variiert)

Latenz einer fetch-Anfrage bestimmen

const misseLatenz = async (url) => {
  const t0 = performance.now();
  const res = await fetch(url);
  await res.text();
  const t1 = performance.now();
  return Math.round(t1 - t0);
};

const ms = await misseLatenz('https://example.com/');
console.log(`Antwort nach ${ms} ms`);
Antwort nach 183 ms (Wert variiert)

Bildrate-unabhängige Animation mit Delta-Zeit

const box = document.querySelector('#box');
const geschwindigkeit = 0.2; // Pixel pro Millisekunde
let x = 0;
let letzte = performance.now();

const tick = (jetzt) => {
  // jetzt ist ein DOMHighResTimeStamp auf derselben Zeitbasis wie performance.now()
  const delta = jetzt - letzte;
  letzte = jetzt;
  x = (x + geschwindigkeit * delta) % window.innerWidth;
  box.style.transform = `translateX(${x}px)`;
  requestAnimationFrame(tick);
};

requestAnimationFrame(tick);

Absoluten Zeitstempel berechnen

const absolut = performance.timeOrigin + performance.now();
console.log(new Date(absolut).toISOString());
console.log(Math.abs(absolut - Date.now()) < 50);
2024-05-14T09:12:33.418Z true

// Wichtig · Fallstricke

  • Reduzierte Genauigkeit: Zum Schutz vor Timing-Angriffen (Spectre) runden Browser den Wert, z. B. auf 100 µs (Chrome) oder 1 ms (Firefox mit privacy.resistFingerprinting). Nur bei cross-origin-isolierten Seiten (Cross-Origin-Opener-Policy + Cross-Origin-Embedder-Policy, prüfbar per crossOriginIsolated) gibt es feinere Auflösung, ca. 5 µs.
  • Nicht mit Date.now() mischen: Beide Werte haben unterschiedliche Bezugspunkte; Differenzen nur zwischen Werten derselben Quelle bilden.
  • Unterschiedliche Zeitbasen: Fenster, iframes und Worker haben je einen eigenen timeOrigin. Werte über postMessage hinweg daher über timeOrigin umrechnen.
  • Schlafzustand: Ob die Zeit im Standby des Geräts weiterläuft, ist browserabhängig (Spezifikation sieht Weiterlaufen vor, ältere Chrome-Versionen pausierten).
  • Benchmarks: Einzelmessungen schwanken stark (JIT-Aufwärmphase, GC). Mehrfach messen und Median bilden.
  • In Node.js global verfügbar ab Version 16, vorher über require('perf_hooks').performance.