Skip to content

feat(browser): Add afterStartPageloadSpan hook to improve spanId assignment on web vital spans #16893

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 11, 2025

Conversation

Lms24
Copy link
Member

@Lms24 Lms24 commented Jul 10, 2025

Our standalone web vital spans need to include the span id of the pageload span s.t. we can correctly assign the web vital value to the respective pageload span in the Sentry backend.

In the previous implementation, we'd simply wait for a tick after tracking the web vitals, get the active root span and take its spanId if it was a pageload span. However, this relies on the assumption that the pageload span is indeed started immediately. By default this happens but users can always deactivate default behaviour and call startBrowserTracingPageloadSpan whenever they want (for example, in a custom browserTracingIntegration).
Furthermore, this "wait for a tick" logic always bugged me and was only done because getClient() would not yet return the already initialized client.

This PR now makes the pageload spanId retrieval more robust by

  • adding and listening to a new SDK lifecycle hook: afterStartPageloadSpan. This callback fires as soon as the pageload span is actually started and available.
  • passing the client from the browserTracingIntegration's setup hook into the web vital listening function so that we can remove the setTimeout(_, 0) logic.

@Lms24 Lms24 changed the base branch from develop to lms/ref-browser-report-event-lcp-cls July 10, 2025 12:40
Copy link
Contributor

github-actions bot commented Jul 10, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 23.88 kB - -
@sentry/browser - with treeshaking flags 22.35 kB - -
@sentry/browser (incl. Tracing) 39.74 kB -0.01% -2 B 🔽
@sentry/browser (incl. Tracing, Replay) 77.87 kB -0.01% -4 B 🔽
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 67.7 kB -0.02% -8 B 🔽
@sentry/browser (incl. Tracing, Replay with Canvas) 82.57 kB -0.01% -2 B 🔽
@sentry/browser (incl. Tracing, Replay, Feedback) 94.67 kB -0.01% -8 B 🔽
@sentry/browser (incl. Feedback) 40.57 kB - -
@sentry/browser (incl. sendFeedback) 28.56 kB - -
@sentry/browser (incl. FeedbackAsync) 33.46 kB - -
@sentry/react 25.61 kB - -
@sentry/react (incl. Tracing) 41.71 kB +0.01% +2 B 🔺
@sentry/vue 28.31 kB - -
@sentry/vue (incl. Tracing) 41.53 kB -0.02% -8 B 🔽
@sentry/svelte 23.9 kB - -
CDN Bundle 25.16 kB - -
CDN Bundle (incl. Tracing) 39.41 kB -0.02% -7 B 🔽
CDN Bundle (incl. Tracing, Replay) 75.37 kB -0.02% -15 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) 80.85 kB -0.02% -10 B 🔽
CDN Bundle - uncompressed 73.5 kB - -
CDN Bundle (incl. Tracing) - uncompressed 116.91 kB +0.03% +24 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 231.09 kB +0.02% +24 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 243.9 kB +0.01% +24 B 🔺
@sentry/nextjs (client) 43.33 kB -0.01% -2 B 🔽
@sentry/sveltekit (client) 40.2 kB -0.02% -5 B 🔽
@sentry/node 167.57 kB - -
@sentry/node - without tracing 100.3 kB -0.01% -1 B 🔽
@sentry/aws-serverless 128.41 kB -0.01% -1 B 🔽

View base workflow run

Base automatically changed from lms/ref-browser-report-event-lcp-cls to develop July 11, 2025 07:52
@Lms24 Lms24 force-pushed the lms/feat-browser-afterStartPageloadSpan branch from f66980a to 74a7f92 Compare July 11, 2025 10:06
@Lms24 Lms24 self-assigned this Jul 11, 2025
@Lms24 Lms24 force-pushed the lms/feat-browser-afterStartPageloadSpan branch from 74a7f92 to f54d641 Compare July 11, 2025 10:42
@Lms24 Lms24 marked this pull request as ready for review July 11, 2025 12:23
@Lms24 Lms24 requested review from s1gr1d, a team and AbhiPrasad and removed request for a team July 11, 2025 12:23
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: Web Vital Reporting Callback Timing Issue

The listenForWebVitalReportEvents function introduces two bugs:

  1. The onHidden callback now unconditionally calls _runCollectorCallbackOnce, which sets the collected flag to true. This can occur before the pageloadSpanId is available, preventing the collectorCallback from being triggered by subsequent navigation events.
  2. A ReferenceError occurs because the unsubscribeAfterStartPageLoadSpan variable is accessed in the beforeStartNavigationSpan callback before its declaration.

packages/browser-utils/src/metrics/utils.ts#L220-L237

onHidden(() => {
_runCollectorCallbackOnce('pagehide');
});
const unsubscribeStartNavigation = client.on('beforeStartNavigationSpan', (_, options) => {
// we only want to collect LCP if we actually navigate. Redirects should be ignored.
if (!options?.isRedirect) {
_runCollectorCallbackOnce('navigation');
unsubscribeStartNavigation?.();
unsubscribeAfterStartPageLoadSpan?.();
}
});
const unsubscribeAfterStartPageLoadSpan = client.on('afterStartPageLoadSpan', span => {
pageloadSpanId = span.spanContext().spanId;
unsubscribeAfterStartPageLoadSpan?.();
});

Fix in CursorFix in Web


Was this report helpful? Give feedback by reacting with 👍 or 👎

@Lms24 Lms24 merged commit 2912474 into develop Jul 11, 2025
331 of 333 checks passed
@Lms24 Lms24 deleted the lms/feat-browser-afterStartPageloadSpan branch July 11, 2025 15:40
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.

2 participants