Start · Sprachen · JavaScript · Referenz · LayoutShiftAttribution.node

LayoutShiftAttribution.node

Eigenschaft

Schreibgeschützte Eigenschaft, die den DOM-<code>Node</code> liefert, der bei einer Layout-Verschiebung bewegt wurde, oder <code>null</code>, wenn er nicht mehr existiert.

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

Signatur

LayoutShiftAttribution.node

Beschreibung

Die Eigenschaft node eines LayoutShiftAttribution-Objekts gibt das DOM-Element (genauer: den Node) zurück, das bei einem Layout-Shift seine Position verändert hat. Mehrere solcher Attributionen findest du im Array LayoutShift.sources. Dieses Array gehört zu einem Performance-Eintrag vom Typ "layout-shift", den du mit einem PerformanceObserver erhältst.

Gebraucht wird die Eigenschaft vor allem, um den Cumulative Layout Shift (CLS) zu debuggen, also eine der Core Web Vitals. Der CLS-Wert allein zeigt nur, wie stark sich das Layout verschoben hat. Über node erfährst du, welche Elemente sich bewegt haben, zum Beispiel ein Banner, das nachträglich eingefügt wird, oder ein Bild ohne feste Abmessungen.

Der Browser liefert höchstens fünf Quellen pro Layout-Shift, und zwar die mit der größten Auswirkung. Oft ist node nicht das Element, das die Verschiebung verursacht hat, sondern ein Element, das dadurch verschoben wurde. Um die eigentliche Ursache zu finden, lohnt sich meist ein Blick auf das vorherige Geschwister- oder das Elternelement.

Rückgabewert

Typ
Node | null
Beschreibung
Der verschobene Node, meist ein Element, manchmal auch ein Textknoten. null, wenn der Knoten inzwischen aus dem DOM entfernt wurde oder der Browser ihn nicht preisgibt.

Beispiele

Verschobene Elemente in der Konsole ausgeben

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // Verschiebungen direkt nach einer Nutzereingabe zählen nicht zum CLS
    if (entry.hadRecentInput) continue;

    for (const source of entry.sources) {
      console.log('Verschoben:', source.node, 'Wert:', entry.value.toFixed(4));
    }
  }
});

observer.observe({ type: 'layout-shift', buffered: true });
Verschoben: <img class="hero"> Wert: 0.1123

Lesbaren Selektor für das Monitoring erzeugen

const describeNode = (node) => {
  if (!node) return '(entfernt)';
  if (node.nodeType !== Node.ELEMENT_NODE) {
    return `#text in ${describeNode(node.parentElement)}`;
  }
  const id = node.id ? `#${node.id}` : '';
  const cls = node.classList.length ? `.${[...node.classList].join('.')}` : '';
  return `${node.tagName.toLowerCase()}${id}${cls}`;
};

new PerformanceObserver((list) => {
  const report = list.getEntries()
    .filter((e) => !e.hadRecentInput)
    .flatMap((e) => e.sources.map((s) => ({
      selector: describeNode(s.node),
      value: e.value
    })));

  if (report.length) {
    // An einen Analytics-Endpunkt senden
    navigator.sendBeacon('/cls-report', JSON.stringify(report));
  }
}).observe({ type: 'layout-shift', buffered: true });

Verschobene Elemente zum Debuggen hervorheben

new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    for (const { node } of entry.sources) {
      if (node instanceof HTMLElement) {
        node.style.outline = '3px solid red';
        setTimeout(() => { node.style.outline = ''; }, 2000);
      }
    }
  }
}).observe({ type: 'layout-shift', buffered: true });

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die Layout Instability API gibt es nur in Chromium-basierten Browsern. Prüfe die Unterstützung vorher, zum Beispiel mit PerformanceObserver.supportedEntryTypes.includes('layout-shift').
  • node kann null sein, etwa wenn das Element nach der Verschiebung aus dem DOM entfernt wurde. Prüfe den Wert deshalb immer, bevor du darauf zugreifst.
  • Es kann auch ein Textknoten zurückkommen, der keine Eigenschaften wie id oder classList hat. Frage vorher nodeType ab oder verwende instanceof Element.
  • Das verschobene Element ist nicht unbedingt die Ursache der Verschiebung. Häufig liegt die Ursache in einem Element davor, zum Beispiel einem nachgeladenen Werbeblock.
  • Speichere keine dauerhaften Referenzen auf die Knoten in globalen Arrays. Sonst kann der Speicher entfernter DOM-Teile nicht freigegeben werden, und es entstehen Speicherlecks. Wandle die Knoten für Berichte besser gleich in Selektor-Strings um.
  • Pro LayoutShift-Eintrag werden höchstens fünf Quellen gemeldet.