@@ -95,6 +95,19 @@ interface Activity {
9595const global = getGlobalObject < Window > ( ) ;
9696const defaultTracingOrigins = [ 'localhost' , / ^ \/ / ] ;
9797
98+ if ( global . performance ) {
99+ // Polyfill for performance.timeOrigin.
100+ //
101+ // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin
102+ // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.
103+ // tslint:disable-next-line:strict-type-predicates
104+ if ( performance . timeOrigin === undefined ) {
105+ // @ts -ignore
106+ // tslint:disable-next-line:deprecation
107+ performance . timeOrigin = performance . timing . navigationStart ;
108+ }
109+ }
110+
98111/**
99112 * Tracing Integration
100113 */
@@ -382,15 +395,11 @@ export class Tracing implements Integration {
382395 // Gatekeeper if performance API not available
383396 return ;
384397 }
398+
385399 logger . log ( '[Tracing] Adding & adjusting spans using Performance API' ) ;
386- let navigationOffset = 0 ;
387- if (
388- transactionSpan . op === 'navigation' &&
389- transactionSpan . data &&
390- typeof transactionSpan . data . offset === 'number'
391- ) {
392- navigationOffset = transactionSpan . data . offset ;
393- }
400+
401+ const timeOrigin = Tracing . _msToSec ( performance . timeOrigin ) ;
402+
394403 // tslint:disable-next-line: completed-docs
395404 function addSpan ( span : SpanClass ) : void {
396405 if ( transactionSpan . spanRecorder ) {
@@ -404,8 +413,8 @@ export class Tracing implements Integration {
404413 description : event ,
405414 op : 'browser' ,
406415 } ) ;
407- span . startTimestamp = parent . startTimestamp + Tracing . _msToSec ( entry [ `${ event } Start` ] ) ;
408- span . timestamp = parent . startTimestamp + Tracing . _msToSec ( entry [ `${ event } End` ] ) ;
416+ span . startTimestamp = timeOrigin + Tracing . _msToSec ( entry [ `${ event } Start` ] ) ;
417+ span . timestamp = timeOrigin + Tracing . _msToSec ( entry [ `${ event } End` ] ) ;
409418 addSpan ( span ) ;
410419 }
411420
@@ -415,15 +424,15 @@ export class Tracing implements Integration {
415424 description : 'request' ,
416425 op : 'browser' ,
417426 } ) ;
418- request . startTimestamp = parent . startTimestamp + Tracing . _msToSec ( entry . requestStart ) ;
419- request . timestamp = parent . startTimestamp + Tracing . _msToSec ( entry . responseEnd ) ;
427+ request . startTimestamp = timeOrigin + Tracing . _msToSec ( entry . requestStart ) ;
428+ request . timestamp = timeOrigin + Tracing . _msToSec ( entry . responseEnd ) ;
420429 addSpan ( request ) ;
421430 const response = parent . child ( {
422431 description : 'response' ,
423432 op : 'browser' ,
424433 } ) ;
425- response . startTimestamp = parent . startTimestamp + Tracing . _msToSec ( entry . responseStart ) ;
426- response . timestamp = parent . startTimestamp + Tracing . _msToSec ( entry . responseEnd ) ;
434+ response . startTimestamp = timeOrigin + Tracing . _msToSec ( entry . responseStart ) ;
435+ response . timestamp = timeOrigin + Tracing . _msToSec ( entry . responseEnd ) ;
427436 addSpan ( response ) ;
428437 }
429438
@@ -469,7 +478,7 @@ export class Tracing implements Integration {
469478 description : `${ entry . entryType } ${ entry . name } ` ,
470479 op : 'mark' ,
471480 } ) ;
472- mark . startTimestamp = transactionSpan . startTimestamp + startTime - navigationOffset ;
481+ mark . startTimestamp = timeOrigin + startTime ;
473482 mark . timestamp = mark . startTimestamp + duration ;
474483 if ( tracingInitMarkStartTime === undefined && entry . name === 'sentry-tracing-init' ) {
475484 tracingInitMarkStartTime = mark . startTimestamp ;
@@ -483,7 +492,7 @@ export class Tracing implements Integration {
483492 if ( transactionSpan . spanRecorder ) {
484493 transactionSpan . spanRecorder . finishedSpans . map ( ( finishedSpan : SpanClass ) => {
485494 if ( finishedSpan . description && finishedSpan . description . indexOf ( resourceName ) !== - 1 ) {
486- finishedSpan . startTimestamp = transactionSpan . startTimestamp + startTime - navigationOffset ;
495+ finishedSpan . startTimestamp = timeOrigin + startTime ;
487496 finishedSpan . timestamp = finishedSpan . startTimestamp + duration ;
488497 }
489498 } ) ;
@@ -493,7 +502,7 @@ export class Tracing implements Integration {
493502 description : `${ entry . initiatorType } ${ resourceName } ` ,
494503 op : `resource` ,
495504 } ) ;
496- resource . startTimestamp = transactionSpan . startTimestamp + startTime - navigationOffset ;
505+ resource . startTimestamp = timeOrigin + startTime ;
497506 resource . timestamp = resource . startTimestamp + duration ;
498507 // We remember the entry script end time to calculate the difference to the first init mark
499508 if ( entryScriptStartEndTime === undefined && ( entryScriptSrc || '' ) . includes ( resourceName ) ) {
@@ -649,10 +658,17 @@ export class Tracing implements Integration {
649658 } ) ;
650659 }
651660 span . finish ( ) ;
652- // If there is an offset in data, we need to shift timestamps towards it
653- if ( span . data && typeof span . data . offset === 'number' && typeof span . timestamp === 'number' ) {
654- span . startTimestamp += span . data . offset ;
655- span . timestamp += span . data . offset ;
661+ // If there is an offset in data, update timestamps accordingly
662+ if (
663+ global . performance &&
664+ span . data &&
665+ typeof span . data . offset === 'number' &&
666+ typeof span . timestamp === 'number'
667+ ) {
668+ const timeOrigin = Tracing . _msToSec ( performance . timeOrigin ) ;
669+ const duration = span . timestamp - span . startTimestamp ;
670+ span . startTimestamp = timeOrigin + span . data . offset ;
671+ span . timestamp = timeOrigin + duration ;
656672 }
657673 }
658674 // tslint:disable-next-line: no-dynamic-delete
0 commit comments