Start · Sprachen · JavaScript · Referenz · LargestContentfulPaint.paintTime

LargestContentfulPaint.paintTime

Eigenschaft

Nur lesbarer Zeitstempel (<code>DOMHighResTimeStamp</code>), der angibt, wann für das LCP-Element die Renderphase endete und die Malphase (Paint) begann.

seit JavaScript Experimentell: bislang nur neuere Chromium-Browser Kategorie: webapi

Signatur

LargestContentfulPaint.paintTime

Beschreibung

Die schreibgeschützte Eigenschaft paintTime eines LargestContentfulPaint-Eintrags gibt den Zeitpunkt an, an dem der Browser die Renderphase des Frames abgeschlossen und mit der Malphase begonnen hat. Das ist der Frame, in dem das größte sichtbare Inhaltselement (Bild, Textblock, Video-Poster usw.) zum ersten Mal gezeichnet wurde. Der Wert ist ein DOMHighResTimeStamp in Millisekunden, relativ zu performance.timeOrigin.

paintTime kommt aus dem PaintTimingMixin der Paint-Timing-Spezifikation und steht zusammen mit presentationTime zur Verfügung. paintTime markiert den Beginn des Malens auf dem Hauptthread. presentationTime dagegen gibt an, wann die Pixel tatsächlich auf dem Bildschirm zu sehen waren (nach Rasterung, Compositing und VSync). Der Abstand zwischen beiden Werten zeigt, wie viel Zeit im Compositor bzw. in der GPU-Pipeline vergeht.

Nützlich ist die Eigenschaft vor allem für genaue Core-Web-Vitals-Analysen: Zieht man loadTime (Ressource geladen) von paintTime ab, sieht man die Render-Verzögerung des LCP-Elements, also z. B. Wartezeit durch blockierende Skripte, Layout oder Stylesheets. Das hilft beim Unterscheiden, ob ein schlechter LCP-Wert am Netzwerk oder am Rendering liegt.

Rückgabewert

Typ
DOMHighResTimeStamp
Beschreibung
Zeitstempel in Millisekunden (relativ zu performance.timeOrigin), an dem die Renderphase endete und die Malphase für das LCP-Element begann. Bei ursprungsfremden Bildern ohne Timing-Allow-Origin-Header kann der Wert vergröbert sein.

Beispiele

paintTime des LCP-Kandidaten protokollieren

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if ('paintTime' in entry) {
      console.log('LCP-Element:', entry.element?.tagName);
      console.log('paintTime:', entry.paintTime.toFixed(1), 'ms');
    } else {
      console.log('paintTime nicht unterstützt, startTime:', entry.startTime);
    }
  }
});

observer.observe({ type: 'largest-contentful-paint', buffered: true });
LCP-Element: IMG paintTime: 1234.5 ms

Render-Verzögerung und Präsentationsdauer berechnen

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lcp = entries[entries.length - 1]; // letzter = aktueller LCP-Kandidat
  if (!('paintTime' in lcp)) return;

  // loadTime ist bei Text-Elementen 0
  const renderDelay = lcp.loadTime > 0 ? lcp.paintTime - lcp.loadTime : null;
  const presentationDelay = lcp.presentationTime
    ? lcp.presentationTime - lcp.paintTime
    : null;

  console.table({
    loadTime: lcp.loadTime,
    paintTime: lcp.paintTime,
    presentationTime: lcp.presentationTime,
    renderDelay,
    presentationDelay,
  });
}).observe({ type: 'largest-contentful-paint', buffered: true });
┌───────────────────┬────────┐ │ loadTime │ 980.2 │ │ paintTime │ 1210.4 │ │ presentationTime │ 1226.9 │ │ renderDelay │ 230.2 │ │ presentationDelay │ 16.5 │ └───────────────────┴────────┘

Wert mit Fallback an ein Analytics-Backend senden

let lastLcp;

new PerformanceObserver((list) => {
  lastLcp = list.getEntries().at(-1);
}).observe({ type: 'largest-contentful-paint', buffered: true });

// Beim Verlassen der Seite endgültigen Wert senden
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState !== 'hidden' || !lastLcp) return;
  const payload = {
    lcp: lastLcp.startTime,
    paintTime: lastLcp.paintTime ?? null, // null in nicht unterstützenden Browsern
    url: lastLcp.url || null,
  };
  navigator.sendBeacon('/analytics/lcp', JSON.stringify(payload));
});

// Wichtig · Fallstricke

  • Experimentell: paintTime (und presentationTime) werden derzeit nur von neueren Chromium-Browsern unterstützt. Prüfe vor der Nutzung mit 'paintTime' in entry und greife sonst auf startTime bzw. renderTime zurück.
  • paintTime ist nicht der Zeitpunkt, an dem der Nutzer die Pixel sieht. Dafür ist presentationTime gedacht, dessen Genauigkeit aber vom Browser abhängt und das auch fehlen kann.
  • Bei ursprungsfremden Bildern ohne Timing-Allow-Origin-Antwortheader können Zeitwerte aus Sicherheitsgründen (Timing-Angriffe) vergröbert werden.
  • Pro Seitenaufruf können mehrere LCP-Einträge entstehen. Maßgeblich ist der letzte vor der ersten Nutzereingabe bzw. bevor der Tab in den Hintergrund wechselt.
  • Bei Text-Elementen ist loadTime gleich 0. Rechnungen wie paintTime - loadTime ergeben dort keinen Sinn.