Start · Sprachen · JavaScript · Referenz · LayoutShiftAttribution.currentRect

LayoutShiftAttribution.currentRect

Eigenschaft

Schreibgeschützte Eigenschaft, die als <code>DOMRectReadOnly</code> die Position und Größe des verschobenen Elements im Viewport <em>nach</em> dem Layout-Shift liefert.

seit JavaScript Chromium-basierte Browser (Chrome/Edge 84+, Opera) Kategorie: webapi

Signatur

LayoutShiftAttribution.currentRect

Beschreibung

currentRect gehört zur Schnittstelle LayoutShiftAttribution, die über das Array LayoutShift.sources bereitgestellt wird. Jede Attribution beschreibt ein Element, das bei einer Layout-Verschiebung seine Position geändert hat. currentRect enthält das Rechteck dieses Elements nach der Verschiebung. Das Gegenstück dazu ist previousRect mit dem Zustand vor der Verschiebung.

Die Koordinaten gelten relativ zum Viewport und werden in CSS-Pixeln angegeben. Vergleicht man currentRect mit previousRect, sieht man, wie weit und in welche Richtung sich ein Element bewegt hat. So lassen sich die Ursachen eines schlechten Cumulative Layout Shift (CLS)-Werts finden, etwa nachgeladene Bilder ohne feste Maße, eingeblendete Werbebanner oder das Nachladen von Webfonts.

Typischerweise liest man die Eigenschaft in einem PerformanceObserver mit dem Eintragstyp "layout-shift" aus. Hat ein Element den Viewport durch die Verschiebung verlassen, ist das Rechteck leer: Alle Werte (x, y, width, height) sind dann 0.

Rückgabewert

Typ
DOMRectReadOnly
Beschreibung
Ein unveränderliches Rechteck mit x, y, width, height, top, right, bottom und left. Es gibt die Lage des Elements im Viewport nach der Verschiebung an. Liegt das Element nicht mehr im Viewport, sind alle Werte 0.

Beispiele

Verschobene Elemente mit neuer Position protokollieren

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

    for (const source of entry.sources) {
      const { x, y, width, height } = source.currentRect;
      console.log('Element:', source.node);
      console.log(`Neue Position: x=${x}, y=${y}, ${width}×${height}px`);
    }
  }
});

observer.observe({ type: 'layout-shift', buffered: true });
Element: <div class="hero">…</div> Neue Position: x=0, y=320, 1280×400px

Verschiebungsweg aus previousRect und currentRect berechnen

const getShiftDistance = (source) => {
  const prev = source.previousRect;
  const curr = source.currentRect;
  return {
    dx: curr.x - prev.x,
    dy: curr.y - prev.y,
  };
};

new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    entry.sources.forEach((source) => {
      const { dx, dy } = getShiftDistance(source);
      console.log(`${source.node?.nodeName ?? '(entfernt)'} verschoben um dx=${dx}px, dy=${dy}px`);
    });
  });
}).observe({ type: 'layout-shift', buffered: true });
IMG verschoben um dx=0px, dy=250px

Elemente erkennen, die aus dem Viewport geschoben wurden

const isEmptyRect = (rect) =>
  rect.width === 0 && rect.height === 0 && rect.x === 0 && rect.y === 0;

new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    for (const source of entry.sources) {
      if (isEmptyRect(source.currentRect)) {
        console.warn('Element hat den Viewport verlassen:', source.node);
      }
    }
  }
}).observe({ type: 'layout-shift', buffered: true });
Element hat den Viewport verlassen: <p class="teaser">…</p>

Verschiebungen im Debug-Modus sichtbar machen

const highlight = ({ x, y, width, height }) => {
  const box = document.createElement('div');
  box.className = 'cls-debug-box'; // Styling über externes CSS
  Object.assign(box.style, {
    position: 'fixed',
    left: `${x}px`,
    top: `${y}px`,
    width: `${width}px`,
    height: `${height}px`,
  });
  document.body.append(box);
  setTimeout(() => box.remove(), 2000);
};

if (PerformanceObserver.supportedEntryTypes?.includes('layout-shift')) {
  new PerformanceObserver((list) => {
    list.getEntries().forEach((entry) =>
      entry.sources.forEach((s) => highlight(s.currentRect))
    );
  }).observe({ type: 'layout-shift' });
}

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Die Layout Instability API gibt es nur in Chromium-basierten Browsern (Chrome, Edge, Opera). Firefox und Safari unterstützen sie nicht. Vorher prüfen, z. B. mit PerformanceObserver.supportedEntryTypes.includes('layout-shift').
  • Viewport-Koordinaten: Die Werte beziehen sich auf den Viewport, nicht auf das Dokument. Scrollt die Seite, sind die Rechtecke nicht mit Seitenkoordinaten vergleichbar. Bei Bedarf scrollX/scrollY addieren.
  • Leeres Rechteck: Wurde das Element aus dem Viewport geschoben, sind alle Werte 0. Das ist kein Fehler.
  • Nur eine Auswahl: sources enthält höchstens fünf Attributionen pro Verschiebung, sortiert nach ihrem Einfluss. Kleinere Verursacher können fehlen.
  • Momentaufnahme: Das Rechteck zeigt den Zustand zum Zeitpunkt der Verschiebung. Die aktuelle Position erhält man stattdessen mit node.getBoundingClientRect(). node kann null sein, wenn das Element inzwischen aus dem DOM entfernt wurde.
  • Einträge mit hadRecentInput === true ausfiltern, weil sie nicht in den CLS-Wert einfließen.