@@ -10,7 +10,6 @@ import type {
1010} from '@sentry/core/browser' ;
1111import {
1212 addNonEnumerableProperty ,
13- browserPerformanceTimeOrigin ,
1413 consoleSandbox ,
1514 dateTimestampInSeconds ,
1615 debug ,
@@ -37,6 +36,7 @@ import {
3736 startInactiveSpan ,
3837 timestampInSeconds ,
3938 TRACING_DEFAULTS ,
39+ browserPerformanceTimeOrigin ,
4040} from '@sentry/core/browser' ;
4141import {
4242 addHistoryInstrumentationHandler ,
@@ -636,13 +636,10 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption
636636
637637 if ( WINDOW . location ) {
638638 if ( instrumentPageLoad ) {
639- const origin = browserPerformanceTimeOrigin ( ) ;
640639 startBrowserTracingPageLoadSpan ( client , {
641640 // With span streaming, span names have to be low cardinality, and there is no route
642641 // information available here.
643642 name : hasSpanStreamingEnabled ( client ) ? PAGELOAD_SPAN_NAME_FALLBACK : WINDOW . location . pathname ,
644- // pageload should always start at timeOrigin (and needs to be in s, not ms)
645- startTime : origin ? origin / 1000 : undefined ,
646643 attributes : {
647644 [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'url' ,
648645 [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.pageload.browser' ,
@@ -720,12 +717,23 @@ export function startBrowserTracingPageLoadSpan(
720717 spanOptions : StartSpanOptions ,
721718 traceOptions ?: { sentryTrace ?: string | undefined ; baggage ?: string | undefined } ,
722719) : Span | undefined {
723- client . emit ( 'startPageLoadSpan' , spanOptions , traceOptions ) ;
724-
725720 // `Pageload` is a low-cardinality span name, not a description of the page. The scope's
726721 // transaction name is what error events are grouped by, so it keeps the URL instead.
727722 const isFallbackSpanName = spanOptions . name === PAGELOAD_SPAN_NAME_FALLBACK ;
728723 getCurrentScope ( ) . setTransactionName ( isFallbackSpanName ? WINDOW . location ?. pathname : spanOptions . name ) ;
724+ // A pageload span always covers the entire page load, no matter how late the SDK or a routing
725+ // instrumentation gets around to starting it. Everything that happened before (DNS, TLS, TTFB,
726+ // HTML parsing, chunk loading) is part of the page load and the performance child spans we attach
727+ // later are anchored at the time origin anyway.
728+ const timeOrigin = browserPerformanceTimeOrigin ( ) ;
729+ const pageloadSpanOptions : StartSpanOptions = {
730+ ...spanOptions ,
731+ // startTime needs to be in seconds, not ms
732+ startTime : spanOptions . startTime ?? ( timeOrigin ? timeOrigin / 1000 : undefined ) ,
733+ } ;
734+
735+ client . emit ( 'startPageLoadSpan' , pageloadSpanOptions , traceOptions ) ;
736+ getCurrentScope ( ) . setTransactionName ( pageloadSpanOptions . name ) ;
729737
730738 const pageloadSpan = getActiveIdleSpan ( client ) ;
731739
0 commit comments