Start · Sprachen · JavaScript · Referenz · PerformanceObserver.observe()

PerformanceObserver.observe()

Methode

Legt fest, welche Performance-Eintragstypen (z. B. <code>resource</code>, <code>paint</code>, <code>largest-contentful-paint</code>) der Observer beobachtet und an seinen Callback meldet.

seit JavaScript Baseline: alle modernen Browser (Option type/buffe Kategorie: webapi

Signatur

PerformanceObserver.prototype.observe(options)

Beschreibung

Mit observe() meldest du einen PerformanceObserver für einen oder mehrere Performance-Eintragstypen an. Sobald der Browser passende Einträge erzeugt, zum Beispiel für geladene Ressourcen, eigene Marker, lange Tasks oder Web-Vitals-Messwerte, ruft er den im Konstruktor übergebenen Callback mit einer PerformanceObserverEntryList auf.

Es gibt zwei Aufrufformen, die sich gegenseitig ausschließen:

  • entryTypes: Ein Array mehrerer Typen auf einmal. Jeder weitere Aufruf ersetzt die bisherige Liste. Zusätzliche Optionen wie buffered oder durationThreshold sind in dieser Form nicht erlaubt.
  • type: Genau ein Typ pro Aufruf. Hier sind buffered und (bei event) durationThreshold erlaubt. Mehrere Aufrufe mit unterschiedlichen Typen ergänzen sich. Rufst du denselben Typ erneut auf, werden nur dessen Optionen aktualisiert.

Die type-Form mit buffered: true ist heute die empfohlene Variante. Damit bekommst du auch Einträge, die schon vor dem Anmelden des Observers entstanden sind. Das ist wichtig für Messwerte wie LCP oder FCP, weil die Messskripte oft erst spät geladen werden. Welche Typen der Browser unterstützt, verrät PerformanceObserver.supportedEntryTypes.

Parameter

Name Typ Default Beschreibung
$options Pflicht PerformanceObserverInit Konfigurationsobjekt. Es muss entweder entryTypes oder type enthalten, aber nicht beides.
$options.entryTypes string[] Liste der zu beobachtenden Eintragstypen, z. B. ['mark', 'measure', 'resource']. Nicht unterstützte Typen werden ignoriert (mit einer Warnung in der Konsole).
$options.type string Ein einzelner Eintragstyp, z. B. 'largest-contentful-paint', 'longtask', 'event' oder 'layout-shift'.
$options.buffered boolean false Nur zusammen mit type nutzbar. Bei true werden auch bereits gepufferte Einträge geliefert, die vor dem Aufruf entstanden sind.
$options.durationThreshold number 104 Nur für type: 'event': Mindestdauer in Millisekunden, ab der Event-Timing-Einträge gemeldet werden. Der kleinste erlaubte Wert ist 16.

Beispiele

Largest Contentful Paint inklusive gepufferter Einträge messen

const lcpObserver = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const last = entries.at(-1); // der jeweils aktuellste LCP-Kandidat
  console.log('LCP:', Math.round(last.startTime), 'ms', last.element);
});

lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });
LCP: 1234 ms <img class="hero">

Mehrere Typen per entryTypes beobachten (eigene Marker und Messungen)

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log(`${entry.entryType}: ${entry.name} – ${entry.duration.toFixed(1)} ms`);
  }
});

observer.observe({ entryTypes: ['mark', 'measure'] });

performance.mark('daten-start');
await fetch('/api/daten');
performance.mark('daten-ende');
performance.measure('daten-laden', 'daten-start', 'daten-ende');
mark: daten-start – 0.0 ms mark: daten-ende – 0.0 ms measure: daten-laden – 182.4 ms

Typen einzeln hinzufügen, mit Feature-Erkennung

const wanted = ['longtask', 'layout-shift', 'event'];
const supported = PerformanceObserver.supportedEntryTypes;

const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((e) => console.log(e.entryType, Math.round(e.duration ?? 0)));
});

for (const type of wanted.filter((t) => supported.includes(t))) {
  // Die type-Form ergänzt: jeder Aufruf fügt einen weiteren Typ hinzu
  const opts = { type, buffered: true };
  if (type === 'event') opts.durationThreshold = 40;
  observer.observe(opts);
}

// Später beenden und nicht zugestellte Einträge abholen
window.addEventListener('pagehide', () => {
  const rest = observer.takeRecords();
  observer.disconnect();
  console.log('Nicht zugestellt:', rest.length);
});
longtask 87 layout-shift 0 event 64

// Wichtig · Fallstricke

  • Nicht mischen: Wenn du entryTypes und type in einem Aufruf angibst oder keines von beiden, wirft der Browser einen TypeError. Wechselst du bei einem bestehenden Observer von einer Form zur anderen, wirft er einen InvalidModificationError (DOMException).
  • entryTypes ersetzt: Ein zweiter Aufruf mit entryTypes überschreibt die vorherige Liste. Mit type ergänzen sich die Aufrufe dagegen.
  • buffered ignoriert: In Kombination mit entryTypes hat buffered keine Wirkung. Verwende die type-Form.
  • Unbekannte Typen lösen keinen Fehler aus, sie werden still ignoriert (höchstens mit einer Konsolenwarnung). Prüfe deshalb vorher PerformanceObserver.supportedEntryTypes. Typen wie longtask, layout-shift, largest-contentful-paint oder long-animation-frame gibt es teilweise nur in Chromium-Browsern.
  • Der Callback läuft asynchron und gebündelt, nicht sofort pro Eintrag. Vor dem disconnect() kannst du mit takeRecords() Einträge abholen, die noch nicht zugestellt wurden.
  • Der Pufferspeicher ist je nach Typ begrenzt. Bei resource gilt performance.setResourceTimingBufferSize(), standardmäßig 250 Einträge.
  • Die Methode funktioniert auch in Web Workern und in Node.js (perf_hooks). Dort stehen jeweils andere Eintragstypen zur Verfügung.