Signatur
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
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 });
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 });
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
0hat eine eigene Bedeutung: Er heißt „keine ausschließende Eingabe“ und ist kein echter Zeitstempel. Wer ohne PrüfungstartTime - lastInputTimerechnet, erhält bei0einen irreführend großen Abstand. - Scrollen, Mausbewegungen und Pinch-Zoom zählen nicht als ausschließende Eingabe und setzen
lastInputTimedaher nicht. - Einträge vom Typ
layout-shiftlassen sich nicht überperformance.getEntriesByType()abrufen. Nutze stattdessen einenPerformanceObservermitbuffered: true. - Die Genauigkeit des Zeitstempels kann aus Datenschutzgründen reduziert sein (Schutz vor Timing-Angriffen).