Signatur
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
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 });
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');
}
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??odertypeofund greifen Sie aufstartTimezurück. nullist möglich: Auch in unterstützenden Browsern kann der Wertnullsein, 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
paintTimesind 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.