Start · Sprachen · JavaScript · Referenz · PerformanceElementTiming.intersectionRect

PerformanceElementTiming.intersectionRect

Eigenschaft

Gibt ein schreibgeschütztes <code>DOMRectReadOnly</code> zurück: den sichtbaren Ausschnitt des beobachteten Elements im Viewport zum Zeitpunkt des Renderns.

seit JavaScript Chromium 77+ (experimentell, nicht in Firefox/Safa Kategorie: webapi

Signatur

get PerformanceElementTiming.intersectionRect

Beschreibung

Die schreibgeschützte Eigenschaft intersectionRect eines PerformanceElementTiming-Eintrags liefert ein DOMRectReadOnly. Es beschreibt, welcher Teil des Elements beim Rendern im Viewport lag. Gemeint ist die Schnittfläche aus Element-Box und Viewport, also genau der Bereich, den Nutzer tatsächlich zu sehen bekamen.

Solche Einträge gibt es nur für Elemente mit dem HTML-Attribut elementtiming. Du liest sie über einen PerformanceObserver mit dem Eintragstyp "element" aus. Die Werte sind CSS-Pixel relativ zum Viewport (x, y, width, height, top, right, bottom, left).

Wofür das praktisch ist:

  • Du prüfst, ob ein wichtiges Element (Hero-Bild, Überschrift) beim ersten Rendern wirklich sichtbar war oder nur teilweise bzw. gar nicht.
  • Du berechnest den sichtbaren Flächenanteil, um Messwerte zu gewichten. Das ähnelt dem Vorgehen bei Largest Contentful Paint.
  • Du filterst Messungen heraus, bei denen das Element außerhalb des sichtbaren Bereichs lag.

Liegt das Element beim Rendern komplett außerhalb des Viewports, ist das Rechteck leer: width und height sind dann 0.

Rückgabewert

Typ
DOMRectReadOnly
Beschreibung
Der sichtbare Ausschnitt des Elements im Viewport in CSS-Pixeln. Ist das Element nicht sichtbar, hat das Rechteck die Breite und Höhe 0.

Beispiele

Sichtbares Rechteck eines Hero-Bildes ausgeben

// HTML: <img src="hero.jpg" elementtiming="hero-bild">
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    const { x, y, width, height } = entry.intersectionRect;
    console.log(`${entry.identifier}: x=${x}, y=${y}, ${width}×${height}px`);
  }
});

observer.observe({ type: 'element', buffered: true });
hero-bild: x=0, y=64, 1280×540px

Sichtbaren Flächenanteil berechnen

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    const sichtbar = entry.intersectionRect;
    const el = entry.element;
    if (!el) continue; // Element evtl. schon aus dem DOM entfernt

    // Gerenderte Gesamtgröße des Elements
    const gesamt = el.getBoundingClientRect();
    const gesamtFlaeche = gesamt.width * gesamt.height;
    const anteil = gesamtFlaeche > 0
      ? (sichtbar.width * sichtbar.height) / gesamtFlaeche
      : 0;

    console.log(`${entry.identifier}: ${(anteil * 100).toFixed(1)} % sichtbar`);
  }
});

observer.observe({ type: 'element', buffered: true });
hero-bild: 72.4 % sichtbar

Nur Einträge sichtbarer Elemente an die Analytics senden

const observer = new PerformanceObserver((list) => {
  const sichtbareEintraege = list.getEntries()
    .filter((e) => e.intersectionRect.width > 0 && e.intersectionRect.height > 0)
    .map((e) => ({
      id: e.identifier,
      renderTime: Math.round(e.renderTime || e.loadTime),
      flaeche: Math.round(e.intersectionRect.width * e.intersectionRect.height)
    }));

  if (sichtbareEintraege.length > 0) {
    navigator.sendBeacon('/analytics/element-timing', JSON.stringify(sichtbareEintraege));
  }
});

if (PerformanceObserver.supportedEntryTypes?.includes('element')) {
  observer.observe({ type: 'element', buffered: true });
}

// Wichtig · Fallstricke

Browser-Kompatibilität: Die Element Timing API ist experimentell. Sie funktioniert nur in Chromium-Browsern (Chrome, Edge, Opera). Firefox und Safari unterstützen sie nicht. Prüfe deshalb vorher, ob PerformanceObserver.supportedEntryTypes.includes('element') wahr ist.

Fallstricke:

  • Der Wert ist eine Momentaufnahme vom Zeitpunkt des Renderns. Scrollt der Nutzer später oder ändert sich das Layout, wird der Wert nicht aktualisiert. Wenn du fortlaufend wissen willst, ob ein Element sichtbar ist, nimm stattdessen den IntersectionObserver.
  • Es werden nur Elemente mit dem Attribut elementtiming erfasst. Die einzige Ausnahme sind Kandidaten, die Chromium intern selbst beobachtet.
  • Die Koordinaten beziehen sich auf den Viewport, nicht auf das Dokument. Um Dokument-Koordinaten zu erhalten, musst du die Scroll-Position (scrollX/scrollY) selbst addieren.
  • entry.element kann null sein, etwa wenn das Element inzwischen aus dem DOM entfernt wurde oder in einem Shadow DOM liegt. intersectionRect bleibt trotzdem verfügbar.
  • Ohne buffered: true entgehen dir Einträge, die entstanden sind, bevor der Observer registriert wurde.