Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 17 additions & 20 deletions packages/core/src/utils/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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() (?)
Expand Down
25 changes: 0 additions & 25 deletions packages/core/test/lib/utils/time.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading