PerformanceObserver
PerformanceObserver asynchronously receives browser performance entries as they are recorded, allowing frontend code to monitor metrics such as paints, resources, navigation, and long tasks. It is useful for performance instrumentation because observation is event-driven rather than based on repeatedly polling performance data.
`PerformanceObserver` watches the browser's Performance Timeline and invokes a callback when entries of requested types become available. The callback receives a `PerformanceObserverEntryList`, from which the code can inspect entries such as `PerformanceResourceTiming`, `PerformancePaintTiming`, or `PerformanceLongTaskTiming` when supported.
You create an observer with a callback and then call `observe()` with one or more entry types. For example, `type: "paint"` can observe paint timing entries, while `type: "resource"` can observe resource timing entries. `buffered: true` is useful when you also want entries that were recorded before observation began, subject to the relevant entry type and browser support.
Observation is asynchronous: the browser schedules delivery of matching entries to the callback rather than returning them directly from `observe()`. This makes the API suitable for telemetry and diagnostics without requiring application code to repeatedly query the timeline.
Not every performance entry type is supported in every browser, and some types have additional buffering or permission considerations. Production code should check support with `PerformanceObserver.supportedEntryTypes` or otherwise feature-detect the specific capability it needs.
Key points
- Creates an asynchronous callback for matching Performance Timeline entries.
- Use `observe()` to select the entry type or types of interest.
- `buffered: true` can include eligible entries recorded before observation started.
- Common entry types include `resource`, `navigation`, `paint`, and `longtask`, subject to browser support.
- Disconnect an observer when it is no longer needed to avoid unnecessary callbacks and retained references.
Interview questions
What problem does PerformanceObserver solve?
PerformanceObserver provides an event-driven way to consume entries from the browser's Performance Timeline. Instead of repeatedly checking the timeline, application code registers a callback and receives matching entries asynchronously. This is useful for collecting performance telemetry while reducing unnecessary polling. The exact entries available depend on browser support and the requested entry type.
How do you configure a PerformanceObserver?
First create a `PerformanceObserver` with a callback that processes the supplied entry list. Then call `observe()` with the desired entry type, such as `resource` or `paint`. If earlier buffered entries should be included, use `buffered: true` where supported for that entry type. In production, feature detection is important because supported entry types vary by browser.
What is the difference between `buffered: true` and starting observation normally?
Normal observation focuses on entries delivered after observation is established. With `buffered: true`, the browser can also deliver eligible entries that were already recorded before the observer began watching. This matters for measurements such as paint timing, where an important event may happen before application instrumentation runs. The option is subject to the semantics and support of the particular entry type.
How would you build production performance telemetry with PerformanceObserver?
I would register observers only for metrics that answer a concrete monitoring question and feature-detect the required entry types. The callback would normalize relevant fields into a small telemetry payload, avoid expensive work on the critical path, and batch or defer network transmission. I would also disconnect observers when their scope ends and guard against duplicate instrumentation. Finally, I would account for browser support and distinguish missing measurements from genuinely good performance.
What should you check before relying on a particular PerformanceObserver entry type?
I would verify that the target browsers expose the required entry type and understand any type-specific behavior or restrictions. `PerformanceObserver.supportedEntryTypes` can help identify supported types, although application logic should still be designed around the browsers it actually targets. I would also check whether the desired data is buffered and whether the measurement has privacy, availability, or timing limitations. This prevents a telemetry system from treating unsupported or unavailable measurements as meaningful zeros.