From 18c4670ad366c87a0792cde4a08fd6f542df4445 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Wed, 7 Jan 2026 11:27:34 +0100 Subject: [PATCH] ref(core): Remove dependence between `performance.timeorigin` and `performance.timing.navigationStart` --- packages/core/src/utils/time.ts | 37 +++++++++++------------ packages/core/test/lib/utils/time.test.ts | 25 --------------- 2 files changed, 17 insertions(+), 45 deletions(-) diff --git a/packages/core/src/utils/time.ts b/packages/core/src/utils/time.ts index bfed9386f8bb..202c39da3abe 100644 --- a/packages/core/src/utils/time.ts +++ b/packages/core/src/utils/time.ts @@ -78,12 +78,14 @@ let cachedTimeOrigin: number | null | undefined = null; /** * Gets the time origin and the mode used to determine it. + * + * Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or + * performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin + * data as reliable if they are within a reasonable threshold of the current time. + * * TODO: move to `@sentry/browser-utils` package. */ function getBrowserTimeOrigin(): number | undefined { - // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or - // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin - // data as reliable if they are within a reasonable threshold of the current time. const { performance } = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window; if (!performance?.now) { return undefined; @@ -94,11 +96,13 @@ function getBrowserTimeOrigin(): number | undefined { const performanceNow = performance.now(); const dateNow = Date.now(); - // if timeOrigin isn't available set delta to threshold so it isn't used - const timeOriginDelta = performance.timeOrigin - ? Math.abs(performance.timeOrigin + performanceNow - dateNow) - : threshold; - const timeOriginIsReliable = timeOriginDelta < threshold; + const timeOrigin = performance.timeOrigin; + if (typeof timeOrigin === 'number') { + const timeOriginDelta = Math.abs(timeOrigin + performanceNow - dateNow); + if (timeOriginDelta < threshold) { + return timeOrigin; + } + } // TODO: Remove all code related to `performance.timing.navigationStart` once we drop support for Safari 14. // `performance.timeSince` is available in Safari 15. @@ -111,18 +115,11 @@ function getBrowserTimeOrigin(): number | undefined { // Date API. // eslint-disable-next-line deprecation/deprecation const navigationStart = performance.timing?.navigationStart; - const hasNavigationStart = typeof navigationStart === 'number'; - // if navigationStart isn't available set delta to threshold so it isn't used - const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold; - const navigationStartIsReliable = navigationStartDelta < threshold; - - // TODO: Since timeOrigin explicitly replaces navigationStart, we should probably remove the navigationStartIsReliable check. - if (timeOriginIsReliable && timeOriginDelta <= navigationStartDelta) { - return performance.timeOrigin; - } - - if (navigationStartIsReliable) { - return navigationStart; + if (typeof navigationStart === 'number') { + const navigationStartDelta = Math.abs(navigationStart + performanceNow - dateNow); + if (navigationStartDelta < threshold) { + return navigationStart; + } } // TODO: We should probably fall back to Date.now() - performance.now(), since this is still more accurate than just Date.now() (?) diff --git a/packages/core/test/lib/utils/time.test.ts b/packages/core/test/lib/utils/time.test.ts index e40c607cb409..b6db4df1d479 100644 --- a/packages/core/test/lib/utils/time.test.ts +++ b/packages/core/test/lib/utils/time.test.ts @@ -77,31 +77,6 @@ describe('browserPerformanceTimeOrigin', () => { vi.unstubAllGlobals(); }); - it('returns `performance.timing.navigationStart` if `performance.timeOrigin` is less reliable', async () => { - const currentTimeMs = 1767778040874; - - const navigationStartMs = currentTimeMs - 2_000; - - const timeSincePageloadMs = 1_234.789; - - vi.useFakeTimers(); - vi.setSystemTime(new Date(currentTimeMs)); - - vi.stubGlobal('performance', { - timeOrigin: navigationStartMs - 1, - timing: { - navigationStart: navigationStartMs, - }, - now: () => timeSincePageloadMs, - }); - - const timeOrigin = await getFreshPerformanceTimeOrigin(); - expect(timeOrigin).toBe(navigationStartMs); - - vi.useRealTimers(); - vi.unstubAllGlobals(); - }); - describe('caching', () => { it('caches `undefined` result', async () => { vi.stubGlobal('performance', undefined);