Skip to content

feat(browser): Start a navigation span for bfcache restores - #23748

Draft
logaretm wants to merge 1 commit into
awad/js-1019-soft-nav-web-vitals-spansfrom
awad/bfcache-navigation-span
Draft

feat(browser): Start a navigation span for bfcache restores#23748
logaretm wants to merge 1 commit into
awad/js-1019-soft-nav-web-vitals-spansfrom
awad/bfcache-navigation-span

Conversation

@logaretm

@logaretm logaretm commented Aug 28, 2026

Copy link
Copy Markdown
Member

Starts a navigation span when the page is restored from the back/forward cache.

A restore resurrects the frozen document, so there is no document load and no usable history event: popstate either doesn't fire or is swallowed because the URL is unchanged. Without a span of its own, everything after the restore joins the trace the page had before it was frozen, which misattributes errors and breadcrumbs as much as vitals.

It lives in browserTracingIntegration rather than bfcacheIntegration so it doesn't depend on an opt-in integration being enabled, and carries browser.navigation.type: bfcache since a restore is near-instant and would otherwise drag navigation duration percentiles down with no way to tell it apart.

Stacked on #23425.

@logaretm logaretm changed the title awad/bfcache navigation span feat(browser): Report web vitals for bfcache restores Aug 28, 2026
@logaretm
logaretm force-pushed the awad/bfcache-navigation-span branch from c306449 to 831a206 Compare August 28, 2026 18:39
@logaretm logaretm changed the title feat(browser): Report web vitals for bfcache restores feat(browser): Start a navigation span for bfcache restores Aug 28, 2026
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 28.8 kB +0.4% +114 B 🔺
@sentry/browser - with treeshaking flags 27.11 kB +0.42% +113 B 🔺
@sentry/browser - with treeshaking flags tracing without tracing 27 kB +0.45% +119 B 🔺
@sentry/browser (incl. Tracing) 50.19 kB +2.28% +1.11 kB 🔺
@sentry/browser (incl. Tracing + Span Streaming) 50.2 kB +2.32% +1.14 kB 🔺
@sentry/browser (incl. Tracing, Profiling) 53.16 kB +2.28% +1.18 kB 🔺
@sentry/browser (incl. Tracing, Replay) 89.72 kB +1.33% +1.17 kB 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 78.83 kB +1.27% +982 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 94.41 kB +1.27% +1.18 kB 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 107.39 kB +1.14% +1.21 kB 🔺
@sentry/browser (incl. Feedback) 46.3 kB +0.27% +124 B 🔺
@sentry/browser (incl. sendFeedback) 33.86 kB +0.34% +113 B 🔺
@sentry/browser (incl. FeedbackAsync) 38.97 kB +0.33% +125 B 🔺
@sentry/browser (incl. Metrics) 29.82 kB +0.55% +162 B 🔺
@sentry/browser (incl. Logs) 30.09 kB +0.49% +144 B 🔺
@sentry/browser (incl. Metrics & Logs) 30.75 kB +0.52% +159 B 🔺
@sentry/react 30.55 kB +0.35% +105 B 🔺
@sentry/react (incl. Tracing) 52.5 kB +2.38% +1.22 kB 🔺
@sentry/vue 36.05 kB +0.38% +136 B 🔺
@sentry/vue (incl. Tracing) 52.41 kB +2.1% +1.07 kB 🔺
@sentry/svelte 28.83 kB +0.43% +123 B 🔺
CDN Bundle 30.55 kB +0.41% +124 B 🔺
CDN Bundle (incl. Tracing) 50.68 kB +2.19% +1.08 kB 🔺
CDN Bundle (incl. Logs, Metrics) 32.82 kB +0.49% +160 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 52.62 kB +2.12% +1.09 kB 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 73.52 kB +0.36% +263 B 🔺
CDN Bundle (incl. Tracing, Replay) 88.19 kB +1.26% +1.1 kB 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 90.13 kB +1.31% +1.17 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 94.23 kB +1.29% +1.2 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 96.23 kB +1.33% +1.26 kB 🔺
CDN Bundle - uncompressed 90.46 kB +0.37% +329 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 151.41 kB +2.44% +3.61 kB 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 97.03 kB +0.54% +514 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 157.38 kB +2.47% +3.79 kB 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 226.4 kB +0.32% +714 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 270.98 kB +1.38% +3.68 kB 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 276.93 kB +1.42% +3.87 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 284.69 kB +1.31% +3.68 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 290.63 kB +1.35% +3.87 kB 🔺
@sentry/nextjs (client) 54.82 kB +1.73% +931 B 🔺
@sentry/sveltekit (client) 50.59 kB +2.2% +1.09 kB 🔺
@sentry/core/server 36.99 kB -9.7% -3.97 kB 🔽
@sentry/core/browser 13.55 kB +0.15% +20 B 🔺
@sentry/node 127.86 kB +2.59% +3.22 kB 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 81.61 kB +0.13% +103 B 🔺
@sentry/node - without tracing 88.73 kB +0.3% +260 B 🔺
@sentry/node - without channel injection 107.11 kB +3.07% +3.18 kB 🔺
@sentry/aws-serverless 97.12 kB +0.29% +278 B 🔺
@sentry/cloudflare (withSentry) - minified 201.98 kB +0.21% +419 B 🔺
@sentry/cloudflare (withSentry) 502.68 kB +0.27% +1.31 kB 🔺

View base workflow run

@logaretm
logaretm force-pushed the awad/bfcache-navigation-span branch from 831a206 to d7cd440 Compare August 31, 2026 16:03
@logaretm
logaretm force-pushed the awad/bfcache-navigation-span branch from d7cd440 to e67604c Compare September 8, 2026 14:56
… bfcache

Prototype. A bfcache restore resurrects the frozen document, so there is
no document load and no usable history event: `popstate` either doesn't
fire or is swallowed, because the URL is unchanged from when the page was
frozen. Two independent guards in the existing path suppress it, neither
written with bfcache in mind, so there is no small nudge that gets a span
out of it.

Without one, everything after the restore joins the trace the page had
before it was frozen, separated by however long it sat in the cache. That
misattributes errors, breadcrumbs, clicks and fetches, not just the web
vitals that prompted this.

The span is started from a `pageshow` listener in `browserTracingIntegration`
rather than `bfcacheIntegration`, so it does not depend on an opt-in
integration that is about hit/miss diagnostics. It is gated on
`instrumentNavigation` and on by default.

It carries `browser.navigation.type: bfcache`. A restore is near-instant,
so without a way to filter these out they would drag navigation duration
percentiles down exactly the way bfcache vitals would have dragged LCP.

The span deliberately starts at the `pageshow` event rather than from
`PerformanceNavigationTiming`, which is not replaced on restore and still
describes the original document load.

Known gap, pinned by a test: `bfcacheIntegration` registers its own
`pageshow` listener from `setupOnce`, which core always runs before every
`afterAllSetup`, so its hit/miss metric is emitted before this span exists
and still lands on the pre-freeze trace.
@logaretm
logaretm force-pushed the awad/bfcache-navigation-span branch from e67604c to 08b4500 Compare September 8, 2026 14:57
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