Start · Sprachen · JavaScript · Referenz · LayoutShiftAttribution.toJSON()

LayoutShiftAttribution.toJSON()

Methode

Gibt ein einfaches Objekt zurück, das ein <code>LayoutShiftAttribution</code>-Objekt ohne das DOM-Element <code>node</code> als JSON-taugliche Daten abbildet.

seit JavaScript Chromium 84+ (Chrome, Edge, Opera); nicht in Firef Kategorie: webapi

Signatur

LayoutShiftAttribution.prototype.toJSON()

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

Typ
Object
Beschreibung
Ein einfaches Objekt mit den Eigenschaften 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 });
{ previousRect: { x: 0, y: 120, width: 800, height: 300, top: 120, right: 800, bottom: 420, left: 0 }, currentRect: { x: 0, y: 220, width: 800, height: 300, top: 220, right: 800, bottom: 520, left: 0 } }

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 });
┌─────────┬──────────────────────┬────────┐ │ (index) │ selector │ deltaY │ ├─────────┼──────────────────────┼────────┤ │ 0 │ 'div#banner.promo' │ 100 │ └─────────┴──────────────────────┴────────┘

// Wichtig · Fallstricke

  • Kein node im 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 kann node null sein, 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 mit JSON.stringify().
  • Pro LayoutShift-Eintrag nennt sources hö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.