Start · Sprachen · JavaScript · Referenz · LayoutShift.lastInputTime

LayoutShift.lastInputTime

Eigenschaft

Schreibgeschützte Eigenschaft mit dem Zeitstempel der letzten ausschließenden Nutzereingabe vor einer Layout-Verschiebung, oder <code>0</code>, wenn es keine solche Eingabe gab.

seit JavaScript Experimentell: nur Chromium-Browser (Chrome/Edge 7 Kategorie: webapi

Signatur

LayoutShift.lastInputTime

Beschreibung

Die schreibgeschützte Eigenschaft lastInputTime eines LayoutShift-Eintrags liefert einen DOMHighResTimeStamp. Er gibt an, wann die letzte ausschließende Nutzereingabe stattfand. Ausschließend sind diskrete Eingaben wie Klicks, Tippen auf dem Touchscreen oder Tastendrücke. Layout-Verschiebungen direkt danach gelten als erwartet und zählen nicht zum Cumulative Layout Shift (CLS). Scrollen und Mausbewegungen zählen nicht als ausschließende Eingabe. Gab es keine solche Eingabe, ist der Wert 0.

Wie alle Zeitstempel der Performance-API bezieht sich der Wert auf performance.timeOrigin, also in der Regel auf den Beginn der Navigation. Damit lässt er sich direkt mit entry.startTime vergleichen. Die Differenz startTime - lastInputTime zeigt, wie lange die Eingabe vor der Verschiebung zurücklag.

In der Praxis nutzt man lastInputTime zusammen mit hadRecentInput. hadRecentInput sagt nur, ob eine Verschiebung innerhalb von 500 ms nach einer Eingabe geschah. lastInputTime liefert dazu den genauen Zeitpunkt. Das hilft bei der Fehlersuche, zum Beispiel wenn Inhalte nach einem Klick zu spät nachladen und die Verschiebung knapp außerhalb des 500-ms-Fensters landet.

Rückgabewert

Typ
DOMHighResTimeStamp (number)
Beschreibung
Zeitstempel der letzten ausschließenden Eingabe in Millisekunden, relativ zu performance.timeOrigin, oder 0, wenn keine solche Eingabe stattfand.

Beispiele

Letzte Eingabezeit für jede Layout-Verschiebung ausgeben

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log(
      `Shift bei ${entry.startTime.toFixed(0)} ms, ` +
      `letzte Eingabe: ${entry.lastInputTime.toFixed(0)} ms, ` +
      `Wert: ${entry.value.toFixed(4)}`
    );
  }
});

// buffered: true liefert auch Einträge, die vor dem Beobachten entstanden sind
observer.observe({ type: 'layout-shift', buffered: true });
Shift bei 1834 ms, letzte Eingabe: 0 ms, Wert: 0.0421 Shift bei 5210 ms, letzte Eingabe: 5102 ms, Wert: 0.1187

Abstand zwischen Eingabe und Verschiebung messen

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.lastInputTime === 0) {
      console.log('Keine vorherige Eingabe: Verschiebung zählt zum CLS');
      continue;
    }
    const abstand = entry.startTime - entry.lastInputTime;
    const status = entry.hadRecentInput ? 'ausgeschlossen' : 'zählt zum CLS';
    console.log(`${abstand.toFixed(0)} ms nach Eingabe (${status})`);
  }
});

observer.observe({ type: 'layout-shift', buffered: true });
Keine vorherige Eingabe: Verschiebung zählt zum CLS 108 ms nach Eingabe (ausgeschlossen) 742 ms nach Eingabe (zählt zum CLS)

Verspätete Verschiebungen nach Klicks für das Monitoring sammeln

// Verschiebungen knapp außerhalb des 500-ms-Fensters deuten oft auf
// langsam nachladende Inhalte nach einer Interaktion hin
const verspaetet = [];

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    const abstand = entry.startTime - entry.lastInputTime;
    if (entry.lastInputTime > 0 && !entry.hadRecentInput && abstand < 2000) {
      verspaetet.push({
        abstand: Math.round(abstand),
        wert: entry.value,
        quellen: entry.sources.map((s) => s.node?.nodeName ?? 'unbekannt')
      });
    }
  }
});

if (PerformanceObserver.supportedEntryTypes?.includes('layout-shift')) {
  observer.observe({ type: 'layout-shift', buffered: true });

  addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'hidden' && verspaetet.length) {
      navigator.sendBeacon('/analytics/cls', JSON.stringify(verspaetet));
    }
  });
}

// Wichtig · Fallstricke

  • Kompatibilität: Die Layout Instability API ist experimentell und steht nur in Chromium-Browsern bereit (Chrome, Edge, Opera). Firefox und Safari unterstützen sie nicht. Prüfe die Unterstützung vorher mit PerformanceObserver.supportedEntryTypes.includes('layout-shift').
  • Der Wert 0 hat eine eigene Bedeutung: Er heißt „keine ausschließende Eingabe“ und ist kein echter Zeitstempel. Wer ohne Prüfung startTime - lastInputTime rechnet, erhält bei 0 einen irreführend großen Abstand.
  • Scrollen, Mausbewegungen und Pinch-Zoom zählen nicht als ausschließende Eingabe und setzen lastInputTime daher nicht.
  • Einträge vom Typ layout-shift lassen sich nicht über performance.getEntriesByType() abrufen. Nutze stattdessen einen PerformanceObserver mit buffered: true.
  • Die Genauigkeit des Zeitstempels kann aus Datenschutzgründen reduziert sein (Schutz vor Timing-Angriffen).