Signatur
Beschreibung
Die Methode toJSON() des Interfaces LayoutShiftAttribution ist ein Serializer. Sie gibt ein einfaches JavaScript-Objekt mit den serialisierbaren Eigenschaften der Attribution zurück, also previousRect und currentRect. Die beiden DOMRectReadOnly-Werte werden dabei selbst in Objekte mit x, y, width, height, top, right, bottom und left umgewandelt.
Ein LayoutShiftAttribution-Objekt beschreibt ein einzelnes DOM-Element, das sich bei einer Layout-Verschiebung bewegt hat. Solche Objekte findest du im Array LayoutShift.sources der Einträge vom Typ "layout-shift" der Layout Instability API. Mit toJSON() kannst du diese Daten bequem protokollieren oder an einen Analyse-Endpunkt schicken, etwa um die Ursachen eines schlechten Cumulative Layout Shift (CLS) zu finden.
Die Methode wird selten direkt aufgerufen. JSON.stringify() ruft sie automatisch auf, sobald ein LayoutShiftAttribution-Objekt serialisiert wird, auch wenn es in einem LayoutShift-Eintrag steckt.
Rückgabewert
previousRect und currentRect, jeweils als einfaches Rechteck-Objekt. Die Eigenschaft node fehlt, weil ein DOM-Knoten nicht serialisierbar ist.Beispiele
Attributionen einer Layout-Verschiebung ausgeben
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
for (const source of entry.sources) {
// toJSON() liefert ein einfaches Objekt ohne 'node'
console.log(source.toJSON());
}
}
});
observer.observe({ type: 'layout-shift', buffered: true });
Daten per JSON.stringify an einen Analyse-Endpunkt senden
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Verschiebungen direkt nach einer Nutzereingabe zählen nicht für CLS
if (entry.hadRecentInput) continue;
const payload = {
value: entry.value,
startTime: entry.startTime,
// JSON.stringify ruft toJSON() automatisch auf
sources: entry.sources
};
navigator.sendBeacon('/analytics/cls', JSON.stringify(payload));
}
});
observer.observe({ type: 'layout-shift', buffered: true });
Fehlenden node durch einen eigenen Selektor ersetzen
const describeNode = (node) => {
if (!(node instanceof Element)) return node?.nodeName ?? null;
const id = node.id ? `#${node.id}` : '';
const cls = node.classList.length ? `.${[...node.classList].join('.')}` : '';
return `${node.tagName.toLowerCase()}${id}${cls}`;
};
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
const details = entry.sources.map((source) => ({
...source.toJSON(),
selector: describeNode(source.node) // node selbst ist nicht enthalten
}));
console.table(details.map(({ selector, previousRect, currentRect }) => ({
selector,
deltaY: currentRect.y - previousRect.y
})));
}
}).observe({ type: 'layout-shift', buffered: true });
// Wichtig · Fallstricke
- Kein
nodeim Ergebnis: Das verschobene DOM-Element wird nicht serialisiert. Wenn du wissen willst, welches Element betroffen war, musst du vor dem Senden selbst eine Kennung ableiten, etwa einen CSS-Selektor. Außerdem kannnodenullsein, wenn das Element inzwischen aus dem DOM entfernt wurde. - Browser-Unterstützung: Die Layout Instability API gibt es nur in Chromium-Browsern. Firefox und Safari unterstützen sie nicht. Prüfe die Unterstützung vorher, zum Beispiel mit
PerformanceObserver.supportedEntryTypes.includes('layout-shift'). toJSON()gibt ein Objekt zurück, keinen JSON-String. Den String erzeugst du mitJSON.stringify().- Pro
LayoutShift-Eintrag nenntsourceshöchstens fünf Elemente, nämlich die mit dem größten Einfluss. Die Liste ist also nicht zwingend vollständig. - Die Rechtecke beziehen sich auf den Viewport, nicht auf das Dokument. Scroll-Positionen sind darin nicht eingerechnet.