Skip to content
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

fix: Try to use a better performance API #3356

Merged
merged 12 commits into from
Mar 31, 2021
19 changes: 16 additions & 3 deletions packages/utils/src/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,27 @@ export const browserPerformanceTimeOrigin = ((): number | undefined => {
if (!performance) {
return undefined;
}
if (performance.timeOrigin) {
// If performance APIs are over an hour skewed don't use them
const THRESHOLD = 3600 * 1000;
// eslint-disable-next-line deprecation/deprecation
const navigationStart = performance.timing && performance.timing.navigationStart;
const hasNavigationStart = typeof navigationStart === 'number';
wmak marked this conversation as resolved.
Show resolved Hide resolved
// Unfortunately browsers may report an inaccurate time origin data, which results in poor results in performance
// data. We treat time origin data as reliable if they are either within a reasonable threshold of the current time,
wmak marked this conversation as resolved.
Show resolved Hide resolved

const timeOriginIsReliable = performance.timeOrigin && Math.abs(performance.timeOrigin + performance.now() - Date.now()) < THRESHOLD;
if (performance.timeOrigin && timeOriginIsReliable) {
wmak marked this conversation as resolved.
Show resolved Hide resolved
return performance.timeOrigin;
}
// While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin
// is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.
// Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always
// a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the
// Date API.
wmak marked this conversation as resolved.
Show resolved Hide resolved
// eslint-disable-next-line deprecation/deprecation
return (performance.timing && performance.timing.navigationStart) || Date.now();
const navigationStartIsReliable = Math.abs(navigationStart + performance.now() - Date.now()) < THRESHOLD;
if (hasNavigationStart && navigationStartIsReliable) {
return navigationStart;
}
// Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date.
return Date.now();
})();