diff --git a/packages/utils/src/misc.ts b/packages/utils/src/misc.ts index ecd753794263..31aeec7ca9c9 100644 --- a/packages/utils/src/misc.ts +++ b/packages/utils/src/misc.ts @@ -38,6 +38,13 @@ export function getGlobalObject(): T & SentryGlobal { : fallbackGlobalObject) as T & SentryGlobal; } +/** + * Determines if running in react native + */ +export function isReactNative(): boolean { + return getGlobalObject().navigator?.product === 'ReactNative'; +} + /** * Extended Window interface that allows for Crypto API usage in IE browsers */ @@ -260,7 +267,26 @@ const performanceFallback: CrossPlatformPerformance = { timeOrigin: INITIAL_TIME, }; +/** + * Performance wrapper for react native as performance.now() has been found to start off with an unusual offset. + */ +function getReactNativePerformanceWrapper(): CrossPlatformPerformance { + const INITIAL_OFFSET = performance.now(); + + return { + now(): number { + return performance.now() - INITIAL_OFFSET; + }, + timeOrigin: INITIAL_TIME, + }; +} + export const crossPlatformPerformance: CrossPlatformPerformance = ((): CrossPlatformPerformance => { + // React Native's performance.now() starts with a gigantic offset, so we need to wrap it. + if (isReactNative()) { + return getReactNativePerformanceWrapper(); + } + if (isNodeEnv()) { try { const perfHooks = dynamicRequire(module, 'perf_hooks') as { performance: CrossPlatformPerformance };