Skip to content

Conversation

@joaquin-diaz
Copy link
Contributor

Proposal: Browser Lifecycle Events

Adds a conceptual model for browser lifecycle events, organized into Load, User Interaction, and Unload phases. Includes an event list with purpose, frequency, and status for both semantic conventions and instrumentation.

Goal

Standardize browser telemetry interpretation and guide instrumentation authors.

@joaquin-diaz joaquin-diaz requested a review from a team as a code owner September 15, 2025 13:18
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Sep 15, 2025

CLA Signed

  • ✅login: joaquin-diaz / name: Joaquin Diaz / (efe47b9)

The committers listed above are authorized under a signed CLA.

| `browser.error` | Captures unhandled JavaScript errors. | Not created | Not created |
| `browser.console` | Captures browser console messages such as warnings and logs. | Not created | Not created |
| `browser.user_interaction` | Captures user input events (clicks, scrolls, keypresses) and their latency. | Not created | Not created |
| `browser.performance_resource_timing` | Captures late-loaded assets (ads, analytics, lazy images, etc.). | Not created | Merged (similar) [instrumentation-document-load](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-document-load) |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Karlie-777 has an existing PR for semantic conventions here.

|---|---|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `browser.page_view` | Represents a **soft navigation** (SPA virtual page change). | In review [PR1910](https://github.com/open-telemetry/semantic-conventions/pull/1910) | In review [PR2386](https://github.com/open-telemetry/opentelemetry-js-contrib/pull/2386) |
| `browser.web_vital` | Captures Web Vitals metrics such as CLS, INP, and FID that occur after page load. | Merged [WebVitals](https://opentelemetry.io/docs/specs/semconv/browser/events/#webvital-event) | Not created |
| `browser.error` | Captures unhandled JavaScript errors. | Not created | Not created |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an existing PR for instrumentation here that @wolfgangcodes is taking over (I think). It uses the existing exception.* semantic conventions.

| `browser.web_vital` | Captures Web Vitals metrics such as CLS, INP, and FID that occur after page load. | Merged [WebVitals](https://opentelemetry.io/docs/specs/semconv/browser/events/#webvital-event) | Not created |
| `browser.error` | Captures unhandled JavaScript errors. | Not created | Not created |
| `browser.console` | Captures browser console messages such as warnings and logs. | Not created | Not created |
| `browser.user_interaction` | Captures user input events (clicks, scrolls, keypresses) and their latency. | Not created | Not created |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an existing PR here (also from @Karlie-777).

| `browser.page_view` | Represents a **soft navigation** (SPA virtual page change). | In review [PR1910](https://github.com/open-telemetry/semantic-conventions/pull/1910) | In review [PR2386](https://github.com/open-telemetry/opentelemetry-js-contrib/pull/2386) |
| `browser.web_vital` | Captures Web Vitals metrics such as CLS, INP, and FID that occur after page load. | Merged [WebVitals](https://opentelemetry.io/docs/specs/semconv/browser/events/#webvital-event) | Not created |
| `browser.error` | Captures unhandled JavaScript errors. | Not created | Not created |
| `browser.console` | Captures browser console messages such as warnings and logs. | Not created | Not created |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


| Event | Description | Semantic Conventions Status | Instrumentation Status |
|---|---|---|---|
| `browser.page_unload` | Signals the start of the page unload process. Occurs once per page unload. | Not created | Not created |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this event is necessary. What value would it provide?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could help to determine when the active "Page View" ends, to spend the time spent each view. I think it could be a good thing in theory, but I'm questioning about the reliability of such event, where browsers are not always emitting unload or pagehide events. Users might not understand why this event isn't always present.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unload event is basically deprecated and should not be used due to bfcache. The pagehide event fires also when a document is put into bfcache, which means that the same document can be restored. This implies that it can have a more complex lifecycle than just unload.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also the visibilitychanged event. This does not indicate the end of a document lifecycle (page view?), but could be useful to understand when the user is actually on the page.

|---|---|---|------------------------------------------------------------------------------------------------------------------------------------------------------|
| `browser.page_view` | Signals the start of a **hard** page navigation. Occurs once per page load. | In review [PR1910](https://github.com/open-telemetry/semantic-conventions/pull/1910) | In review [PR2386](https://github.com/open-telemetry/opentelemetry-js-contrib/pull/2386) |
| `browser.navigation_timing` | Captures detailed technical milestones from the [PerformanceNavigationTiming](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming) API. Occurs once per page load. | In review [PR1919](https://github.com/open-telemetry/semantic-conventions/pull/1919) | Not created |
| `browser.page_load` | Summarizes the user-visible page load experience from navigation start until LCP (includes total duration, paint timings, resource counts, transfer size). Occurs once per page load. | Not created | Not created |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the main intent of this event to summarize all the other events that happen during page load to make it easier for backends?

Alternatively

  • duration is part of navigation timing (if based on the window load event)
  • FCP and LCP are part of web vitals
  • resource counts could be determined from resource timing data
  • transfer size is available in resource timing data


| Event | Description | Semantic Conventions Status | Instrumentation Status |
|---|---|---|------------------------------------------------------------------------------------------------------------------------------------------------------|
| `browser.page_view` | Signals the start of a **hard** page navigation. Occurs once per page load. | In review [PR1910](https://github.com/open-telemetry/semantic-conventions/pull/1910) | In review [PR2386](https://github.com/open-telemetry/opentelemetry-js-contrib/pull/2386) |
Copy link
Contributor

@martinkuba martinkuba Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be in favor of calling this navigation event (as proposed here). It would make it clear that it is based on a foundational browser event and aligns with the Web APIs terminology (Navigation timing, Navigate event).

Page view seems more like a derived concept. It is not a term used in the browser spec/terminology. I do concede that it is used in various analytics products, but I am not sure if it has exactly the same meaning everywhere. The name also implies that the user actually saw the page, but that may not always be the case. For example, if the page is loading in a hidden tab, is it still a page view?


| Event | Description | Semantic Conventions Status | Instrumentation Status |
|---|---|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `browser.page_view` | Represents a **soft navigation** (SPA virtual page change). | In review [PR1910](https://github.com/open-telemetry/semantic-conventions/pull/1910) | In review [PR2386](https://github.com/open-telemetry/opentelemetry-js-contrib/pull/2386) |
Copy link
Contributor

@martinkuba martinkuba Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be used only for navigations that follow the soft navigation heuristics? Or, would it be used for any URL change? Or, would it be used for logical page views that may or may not have a URL change?

@martinkuba
Copy link
Contributor

Should we include sessions in this document as well? By lifecycle, do we mean only lifecycle of an HTML document/page, or all the things that happen while the user is using a browser app?


### Load Phase

**Starts at navigation start → Ends at Largest Contentful Paint (LCP)**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: I would avoid using the LCP as a structuring part of the model:

  • it's not supported in all browsers (ex: Safari)
  • It implies that we actually wait for a user interaction before going to the next phase, since LCP entries are notified until a user interaction happens (the Core Web Vital LCP is the time until the latest LCP). This could be problematic on pages that don't have user interactions (ex: a page opened in background).
  • LCP can happen before the page actually finishes to load (before the load event), so correlating to the "Load" phase could be confusing.

Comment on lines +50 to +51
**Starts after LCP → Ends when the page begins unloading**
Captures user-centric metrics, runtime behavior, and late resource loading.
Copy link
Contributor

@BenoitZugmeyer BenoitZugmeyer Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: some events listed in this phase could also belong to the Loading phase, ex: logs, errors... (I'd say also 'user interaction', as a user can interact with a loading page, but it depends on how we determine when the "load" phase ends)

@joaquin-diaz
Copy link
Contributor Author

Closing, following in #6 from fork

@overbalance overbalance deleted the joaquin-diaz/chore/add-browser-lifecycle-docs branch October 23, 2025 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants