Skip to content

feat(rum): add trackWebVitals config to opt out of initial view metrics#15

Merged
Fiona2016 merged 1 commit into
publishfrom
feat/track-web-vitals
Jun 16, 2026
Merged

feat(rum): add trackWebVitals config to opt out of initial view metrics#15
Fiona2016 merged 1 commit into
publishfrom
feat/track-web-vitals

Conversation

@Fiona2016

Copy link
Copy Markdown
Collaborator

Background

A customer integrates the browser SDK into a pre-warmed, hidden Electron BrowserWindow: the window is created with show: false, RUM is initialized immediately, and the actual image content is rendered much later (via IPC) when a preview is needed. RUM then reports an abnormally large LCP.

Root cause

Initial view metrics (FCP / LCP / FID / loading time) are:

  • anchored to the page navigation start (clocksOrigin() in trackViews.ts), not to when init() / startView() is called, and
  • only collected on the INITIAL_LOAD view.

So when content paints long after navigation, LCP = paint - navigationStart, i.e. huge. The existing safeguards don't catch it:

  • trackFirstHidden discards LCP after the page first becomes hidden — but a hidden Electron window does not reliably report document.visibilityState === 'hidden', so the safeguard never triggers.
  • the 10-minute LCP_MAXIMUM_DELAY cap only filters truly extreme values.

Deferring init() / using trackViewsManually + manual startView() does not fix it either, because none of those re-baseline timeOrigin — only a real navigation does.

Change

Add a trackWebVitals init option (default true). When false, trackInitialViewMetrics is not started for that SDK instance, so FCP/LCP/FID/loading-time are simply absent for that page rather than reported as a misleading value. This fits the "separate window has its own init" case cleanly — the preview window opts out, the main app is unaffected.

flashcatRum.init({
  applicationId: '...',
  clientToken: '...',
  trackWebVitals: false, // skip FCP/LCP/FID/loading-time on this (pre-warmed/hidden) page
})

Notes

  • Like profilingSampleRate and propagateTraceBaggage, this fork-specific option is not part of the upstream telemetry schema, so it is intentionally excluded from serializeRumConfiguration (telemetryEvent.types.ts is generated — "DO NOT MODIFY BY HAND"). The exhaustive serializeRumConfiguration test is updated accordingly.
  • Scope is limited to opting out of collection. It does not open the LCP value field in beforeSend (the metric value is deliberately not in the modifiable whitelist).

Tests

  • configuration.spec.ts: trackWebVitals defaults to true, honors provided value, casts to boolean.
  • trackViews.spec.ts: initial view metrics are not collected when trackWebVitals: false.
  • Full unit suite green (2656 passing).

🤖 Generated with Claude Code

Initial view metrics (FCP/LCP/FID/loading time) are anchored to the page
navigation start (`clocksOrigin()`) and only collected on the INITIAL_LOAD
view. For pages that load in the background or are pre-warmed and kept hidden
(e.g. a hidden Electron BrowserWindow that only renders content much later via
IPC), LCP ends up measured from the original navigation and is reported as an
abnormally large value. The existing safeguards (`firstHidden`, the 10-minute
cap) don't help because such hidden windows don't reliably report
`document.visibilityState === 'hidden'`.

Add a `trackWebVitals` init option (default `true`). When set to `false`,
`trackInitialViewMetrics` is not started, so no FCP/LCP/FID/loading-time is
collected for that SDK instance — the field is simply absent rather than a
misleading value.

Like `profilingSampleRate` and `propagateTraceBaggage`, this fork-specific
option is not part of the upstream telemetry schema, so it is intentionally
excluded from `serializeRumConfiguration` (the generated telemetry types must
not be hand-edited).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Fiona2016 Fiona2016 merged commit 1e23f80 into publish Jun 16, 2026
5 checks passed
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.

1 participant