Start · Sprachen · JavaScript · Referenz · PerformanceElementTiming.naturalHeight

PerformanceElementTiming.naturalHeight

Eigenschaft

Gibt die intrinsische Höhe eines beobachteten Bildelements in Pixeln zurück. Bei Textelementen ist der Wert <code>0</code>.

seit JavaScript Chrome/Edge 77+, Opera 64+ (experimentell, nicht i Kategorie: webapi

Signatur

PerformanceElementTiming.naturalHeight

Beschreibung

Die schreibgeschützte Eigenschaft naturalHeight eines PerformanceElementTiming-Eintrags gibt die intrinsische Höhe des Bildes in CSS-Pixeln an, also die Höhe der Bildressource selbst. Wie das Bild per CSS oder HTML-Attribut skaliert dargestellt wird, spielt dafür keine Rolle. Der Wert entspricht damit HTMLImageElement.naturalHeight, steht aber direkt im Performance-Eintrag zur Verfügung. Du musst also nicht mehr auf das DOM-Element zugreifen.

Die Eigenschaft gehört zur Element Timing API. Einträge entstehen nur für Elemente mit dem Attribut elementtiming, zum Beispiel <img elementtiming="hero" src="…">. Die Einträge liest du mit einem PerformanceObserver vom Typ "element" aus.

In der Praxis vergleichst du naturalHeight und naturalWidth mit der tatsächlich gerenderten Größe aus intersectionRect. So findest du überdimensionierte Bilder, die mehr Bytes laden als nötig, und kannst sie zusammen mit renderTime und loadTime an ein Monitoring-System melden.

Bei Textknoten (Einträge mit name === "text-paint") ist der Wert immer 0. Die Eigenschaft ist nur sinnvoll für <img>, für <image> in SVG und für Elemente mit CSS-Hintergrundbild (background-image).

Rückgabewert

Typ
number
Beschreibung
Eine vorzeichenlose Ganzzahl (unsigned long) mit der intrinsischen Bildhöhe in Pixeln. Bei Textelementen 0.

Beispiele

Intrinsische Höhe eines Hero-Bildes auslesen

// HTML: <img src="hero.jpg" elementtiming="hero-bild" width="600">
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.identifier === 'hero-bild') {
      console.log(`Intrinsische Größe: ${entry.naturalWidth}×${entry.naturalHeight}`);
    }
  }
});

// buffered: true liefert auch Einträge, die vor der Registrierung entstanden sind
observer.observe({ type: 'element', buffered: true });
Intrinsische Größe: 2400×1600

Überdimensionierte Bilder erkennen

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // Textelemente haben naturalHeight 0 – überspringen
    if (entry.naturalHeight === 0) continue;

    const gerenderteHoehe = entry.intersectionRect.height;
    if (gerenderteHoehe === 0) continue;

    const faktor = entry.naturalHeight / (gerenderteHoehe * devicePixelRatio);
    if (faktor > 1.5) {
      console.warn(
        `"${entry.identifier}" ist ${faktor.toFixed(1)}× zu hoch ` +
        `(${entry.naturalHeight}px geladen, ${Math.round(gerenderteHoehe)}px sichtbar)`
      );
    }
  }
});

observer.observe({ type: 'element', buffered: true });
"produktfoto" ist 2.7× zu hoch (1600px geladen, 300px sichtbar)

Bild- und Texteinträge unterscheiden und melden

const berichte = [];

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    berichte.push({
      id: entry.identifier,
      art: entry.name === 'text-paint' ? 'text' : 'bild',
      hoehe: entry.naturalHeight, // bei Text immer 0
      breite: entry.naturalWidth,
      renderTime: Math.round(entry.renderTime || entry.loadTime)
    });
  }
});

observer.observe({ type: 'element', buffered: true });

// Beim Verlassen der Seite an den Server schicken
addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden' && berichte.length) {
    navigator.sendBeacon('/rum', JSON.stringify(berichte));
  }
});

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die Element Timing API ist experimentell und nur in Chromium-Browsern verfügbar (Chrome, Edge, Opera). Prüfe die Unterstützung vorher mit PerformanceObserver.supportedEntryTypes.includes('element').
  • Ohne das Attribut elementtiming am Element entsteht kein Eintrag. naturalHeight gibt es dann gar nicht erst.
  • Bei Textelementen ist der Wert immer 0. Filtere solche Einträge vor Berechnungen heraus, sonst teilst du durch null oder bekommst verzerrte Statistiken.
  • Der Wert beschreibt die Bildressource, nicht die Darstellung. Die sichtbare Größe liefert intersectionRect. Bei hochauflösenden Displays solltest du devicePixelRatio einrechnen.
  • Bei Bildern aus anderen Quellen ohne Timing-Allow-Origin-Header ist renderTime 0. naturalHeight bleibt aber verfügbar.
  • Der Wert ist schreibgeschützt. Zuweisungen werden stillschweigend ignoriert.