← Chrome 151 reference

v151 · origin trial · performance · reporting api

Declarative Performance Observer

Limited availability

  • Chrome · origin trial 151–155
  • Edge · no separate signal (Chromium-based)
  • Firefox · no signal
  • Safari · no signal

Not on the Baseline register: a webstatus.dev query (2026-07-28) returns no web-feature entry. There is no BCD entry for this feature; the proposal is pre-incubation (a personal-repository explainer, per the ChromeStatus API record's standards-maturity field) with a WICG proposal still open.

A browser-resident telemetry system that reports performance metrics from navigation initiation to page termination. Activated by a declarative Performance-Observer HTTP response header rather than JavaScript, it captures data even when the request fails with a network error or the renderer process is killed by the OS, and delivers a consolidated report at session termination via the Reporting API.

Origin trial — API surface may move

This feature is in origin trial in Chrome 151–155 on desktop, Android, and WebView (Intent to Experiment; ChromeStatus API record, stage data fetched 2026-07-28). The proposal is pre-incubation and its TAG review is pending, so the header grammar and payload format may change.

at a glance

What it isDeclarative (HTTP-header-driven) activation of browser-process performance telemetry: a Performance-Observer response header selects entry types; the browser collects them out-of-band and POSTs a consolidated report at session end via the Reporting API
What it is notA replacement for the JavaScript PerformanceObserver API, Network Error Logging, or crash reporting (explicit non-goals in the explainer)
ActivationPerformance-Observer HTTP response header on the top-level main-document navigation only — first-party, no JavaScript API, no subresource/iframe activation
DeliveryReporting API: POST with Content-Type: application/reports+json to an endpoint named by the header's report-to directive and defined in Reporting-Endpoints
New entry typePerformanceSessionEndTiming (entryType "session-end") — an anonymous terminal marker giving precise session duration
Chrome statusOrigin trial, Chrome 151–155 (desktop, Android, WebView) — the milestone listing is authoritative (verified 2026-07-28)
Spec statusPre-incubation explainer (“early design sketch”); WICG proposal #280 open; TAG review pending (per the Intent to Experiment)
Tracking bugcrbug.com/505208781
ChromeStatus6594955352080384 — Declarative Performance Observer
Source: Declarative Performance Observer explainer; ChromeStatus API record; Intent to Experiment, fetched 2026-07-28.

why it exists

JavaScript performance APIs are bound to the page's execution environment, so three classes of real user-journey data escape them:

  1. Early network failures. If a navigation fails before any payload arrives (DNS timeout, connection refused, TLS failure), no JavaScript runs and the site never learns the visit happened — success-rate denominators are wrong. NEL captures network errors but cannot correlate them with application journeys.
  2. Abrupt terminations. On out-of-memory kills (common on low-end mobile) or sudden tab closures, unload/pagehide beacons are lost — and unload is deprecated anyway because it breaks BFCache.
  3. Session end. There is no reliable way to timestamp when the user actually left, so dwell time is approximate.

The proposal moves collection into the browser process: events stream out of the renderer as they happen, so an OOM kill cannot take the already-recorded data with it, and the browser itself finalizes the report at the true session boundary.

Source: explainer — introduction and use cases; ChromeStatus motivation.

how it works

  1. The server responds to a top-level navigation with Performance-Observer (selecting entry types and a reporting endpoint) plus a Reporting-Endpoints header defining that endpoint.
  2. The browser process records the requested built-in entries (e.g. navigation, mark, visibility-state) and allowlisted performance.mark()/measure() events for the life of the session — no page JavaScript involved.
  3. On session termination (tab close, navigation away, BFCache entry, early network error, renderer crash), the browser finalizes the payload — appending a terminal PerformanceSessionEndTiming entry — and POSTs it to the endpoint via the Reporting API.
  4. With capture-early-failures, failures that happen before any response (when no header could have been received) are persisted to a bounded on-disk buffer and flushed on the next successful navigation to the same origin.
Source: explainer — potential solution, how this solves the use cases.

report format

The payload is a JSON array of report objects delivered via the Reporting API with Content-Type: application/reports+json. Each report carries the standard Reporting-API fields plus a body whose entries array holds objects extending PerformanceEntry:

[{
  "type": "performance-observer",
  "age": 100,
  "url": "https://www.example.com/second",
  "user_agent": "Mozilla/5.0 … Chrome/146.0.0.0 …",
  "body": {
    "entries": [
      { "name": "https://www.example.com/second", "entryType": "navigation",
        "startTime": 0, "domainLookupStart": 68, "domainLookupEnd": 120,
        "connectStart": 122, "secureConnectionStart": 160,
        "requestStart": 196, "responseStart": 562, "activationStart": 0 },
      { "name": "hero-image-loaded", "entryType": "mark",
        "startTime": 780, "duration": 0,
        "detail": { "additionalinfo": "user defined arbitrary data" } },
      { "name": "hidden", "entryType": "visibility-state",
        "startTime": 13870, "duration": 0 },
      { "name": "session-end-event", "entryType": "session-end",
        "startTime": 240200, "duration": 0 }
    ]
  }
}]
Source: explainer — report format and example report payload.

synthesized navigation entries for early failures

When a network error or early abandonment happens before the response completes, the failure is reported as a synthesized PerformanceNavigationTiming entry: milestones that were never reached (e.g. domainLookupEnd, responseStart, loadEventEnd) are set to 0, so the last non-zero milestone marks where the failure occurred. The explainer's example shows a DNS failure as domainLookupStart: 50 with every subsequent field zeroed.

Source: explainer — example report payload.

capture-early-failures and deferred reporting

On a first-ever navigation that fails before any response, the browser cannot know the origin wanted telemetry — the activating header never arrived. The capture-early-failures directive opts the origin into persisting that intent:

Source: explainer — deferred reporting, deactivation, disk quota, data retention and expiration.

session lifecycle and deactivation

EventBehavior
Header received on top-level navigationActivation: browser begins collecting the requested entries for this document's session
Tab closure / navigation awayReport finalized and dispatched
BFCache entryReport finalized and dispatched; if the page is restored, a new session begins automatically
Early network errorSynthesized zero-filled navigation entry reported (persisted first if no endpoint is available and capture-early-failures opted in)
Renderer crash (e.g. OS OOM kill)Browser process still holds the accumulated payload and flushes it — this is the core reliability win over JS beaconing
Report dispatchedDeactivation: observation does not outlive the document; with no header on the next navigation, nothing is collected, stored, or reported
Source: explainer — activation timing, report timing, deactivation.

examples

Enable telemetry for navigation, marks, and visibility changes, allowlist two application marks, opt into early-failure capture, and name the reporting endpoint:

Reporting-Endpoints: telemetry="https://log.example.com/v1"
Performance-Observer: report-to="telemetry",
                      entry-types=("navigation" "mark" "visibility-state"),
                      include-user-timing=("hero-image-loaded" "next-link-clicked"),
                      capture-early-failures=?1

Emit an allowlisted mark with attached detail from page JavaScript (the only JS involved — collection and delivery remain browser-side):

performance.mark("hero-image-loaded", {
  detail: { additional_info: 12345 }
});
// reported as:
// { "name": "hero-image-loaded", "entryType": "mark",
//   "startTime": 780, "duration": 0,
//   "detail": { "additional_info": 12345 } }

There is no Chrome Platform Showcase demo for this feature yet (the showcase route returns 404 as of 2026-07-28) — server-side header configuration is not meaningfully demonstrable in a client-side demo frame.

Source: explainer — syntax and report format.

browser compatibility

No BCD entry and no webstatus.dev web-feature exists for this proposal (both verified 2026-07-28), so this interim table is built from linked primary sources rather than BCD:

BrowserSupportEvidence
Chrome / Edge (Chromium)Origin trial 151–155 (desktop, Android, WebView)ChromeStatus API record; Intent to Experiment
FirefoxNo signalChromeStatus vendor views (no position recorded)
SafariNo signalChromeStatus vendor views (no position recorded)
WPTNone found upstreamNo declarative-performance-observer directory or test in the web-platform-tests tree (checked 2026-07-28; performance-timeline suite covers only the imperative API)
Source: linked records above, all fetched 2026-07-28.

security & privacy

Source: explainer — security and privacy considerations; self-review questionnaire.

specifications

SpecificationStatus
Declarative Performance Observer (explainer)Pre-incubation — personal-repository proposal, no community adoption (WICG proposal #280 open)
Reporting APIDelivery mechanism (cg-draft)
Performance TimelineDefines PerformanceEntry / PerformanceObserver the payload extends (no declarative variant covered)
Navigation TimingDefines PerformanceNavigationTiming (synthesized on early failures)
User TimingDefines performance.mark()/measure() and detail
High Resolution TimeClock resolution for time-based fields

see also