Start · Sprachen · JavaScript · Referenz · PerformancePaintTiming.presentationTime

PerformancePaintTiming.presentationTime

Eigenschaft

Liefert den Zeitstempel, zu dem die gerenderten Pixel eines Paint-Ereignisses tatsächlich auf dem Bildschirm angezeigt wurden, oder <code>null</code>, wenn der Wert nicht verfügbar ist.

seit JavaScript Experimentell – Chromium 133+; nicht Baseline Kategorie: webapi

Signatur

PerformancePaintTiming.presentationTime

Beschreibung

Die schreibgeschützte Eigenschaft presentationTime eines PerformancePaintTiming-Eintrags (Typ "paint", also first-paint und first-contentful-paint) gibt einen DOMHighResTimeStamp zurück. Er zeigt an, wann das Betriebssystem bzw. der Compositor den fertigen Frame tatsächlich auf dem Display ausgegeben hat.

Sie ergänzt die Eigenschaft paintTime. Diese hält fest, wann die Rendering-Phase im Haupt-Thread des Browsers abgeschlossen war. Die Differenz presentationTime - paintTime zeigt also, wie lange Rasterisierung, Compositing und die Übergabe an die Grafikhardware gedauert haben. Diese Zeit bleibt beim reinen Haupt-Thread-Timing unsichtbar.

Die Eigenschaft ist nützlich für genaue Messungen im Real User Monitoring (RUM): Wer wissen will, wann Nutzer den ersten Inhalt tatsächlich sehen, sollte presentationTime verwenden, falls sie vorhanden ist. Weil sie nicht überall unterstützt wird, braucht man immer einen Rückfall auf startTime oder paintTime.

Rückgabewert

Typ
DOMHighResTimeStamp | null
Beschreibung
Zeit in Millisekunden relativ zu performance.timeOrigin, zu der der Frame angezeigt wurde. Der Wert ist null, wenn die Implementierung den Präsentationszeitpunkt nicht ermitteln kann. Unterstützt der Browser die Eigenschaft gar nicht, ist sie undefined.

Beispiele

First Contentful Paint mit Präsentationszeit messen

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // Rückfall auf startTime, wenn presentationTime fehlt
    const shown = entry.presentationTime ?? entry.startTime;
    console.log(`${entry.name}: ${shown.toFixed(1)} ms`);
  }
});

// buffered: true liefert auch Einträge von vor der Registrierung
observer.observe({ type: 'paint', buffered: true });
first-paint: 412.3 ms first-contentful-paint: 412.3 ms

Verzögerung durch Compositor und Display berechnen

const [fcp] = performance.getEntriesByName('first-contentful-paint');

if (fcp && typeof fcp.presentationTime === 'number' && typeof fcp.paintTime === 'number') {
  const delay = fcp.presentationTime - fcp.paintTime;
  console.log(`Rendering fertig: ${fcp.paintTime.toFixed(1)} ms`);
  console.log(`Auf dem Bildschirm: ${fcp.presentationTime.toFixed(1)} ms`);
  console.log(`Präsentationsverzögerung: ${delay.toFixed(1)} ms`);
} else {
  console.log('presentationTime wird nicht unterstützt');
}
Rendering fertig: 398.7 ms Auf dem Bildschirm: 412.3 ms Präsentationsverzögerung: 13.6 ms

FCP an ein Analytics-Backend senden

const reportFCP = (entry) => {
  const payload = JSON.stringify({
    metric: 'FCP',
    value: Math.round(entry.presentationTime ?? entry.startTime),
    source: entry.presentationTime != null ? 'presentation' : 'start'
  });
  navigator.sendBeacon('/analytics', payload);
};

new PerformanceObserver((list, obs) => {
  const fcp = list.getEntriesByName('first-contentful-paint')[0];
  if (fcp) {
    reportFCP(fcp);
    obs.disconnect();
  }
}).observe({ type: 'paint', buffered: true });

// Wichtig · Fallstricke

  • Kompatibilität: Die Eigenschaft ist experimentell und bisher vor allem in Chromium-Browsern (ab Version 133) verfügbar. In anderen Browsern ist sie undefined. Prüfen Sie deshalb immer mit ?? oder typeof und greifen Sie auf startTime zurück.
  • null ist möglich: Auch in unterstützenden Browsern kann der Wert null sein, wenn die Plattform keinen Präsentationszeitpunkt meldet.
  • Vergröberte Werte: Zum Schutz vor Timing-Angriffen können die Zeitstempel gerundet sein, abhängig von der Cross-Origin-Isolation. Sehr kleine Differenzen zu paintTime sind daher nicht verlässlich.
  • Hintergrund-Tabs: Wird eine Seite im Hintergrund geladen, entstehen oft gar keine Paint-Einträge oder nur stark verzögerte. Solche Werte sollten Sie bei RUM-Auswertungen herausfiltern, etwa über document.visibilityState.
  • Registrieren Sie den Observer mit buffered: true, weil Paint-Ereignisse meist schon vor dem Laden Ihres Skripts stattfinden.