Back to APIs

PerformanceObserver

Observers

An interface to observe performance measurement events and receive notifications of new performance entries (like LCP, CLS, or Long Tasks).

Support96%
BaselineWidely available
ImpactLow
Popularity🔥 60

When to Use

  • Building custom telemetry and RUM solutions.
  • Measuring Core Web Vitals directly from users in production.
  • Detecting Long Tasks that block the main thread and harm INP.

When NOT to Use

  • When a high-level library like `web-vitals` solves your problem with less code.
  • Running intensive data-processing inside the observer callback itself.

Code Examples

Good: Measuring Long Tasks

Uses PerformanceObserver to detect tasks exceeding 50ms without polling.

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log('Main thread blocked for:', entry.duration, 'ms');
  }
});
observer.observe({ type: 'longtask', buffered: true });

Advantages

  • Non-blocking, asynchronous delivery of performance metrics.
  • Able to access buffered historical entries (e.g., LCP elements painted before the script loaded).

Limitations

  • Not all entry types are supported in all browsers (e.g., `largest-contentful-paint` is heavily Chromium-driven).
  • High-frequency events like `resource` timing can flood the observer if not filtered.

Common Mistakes

  • Not using the `buffered: true` flag, causing missed metrics from before the observer initialized.
  • Sending a network request for every single entry instead of batching them.

References