diff --git a/packages/react-native/Libraries/Core/setUpPerformance.js b/packages/react-native/Libraries/Core/setUpPerformance.js index 3f91689eabbf..1a3eaef5abd1 100644 --- a/packages/react-native/Libraries/Core/setUpPerformance.js +++ b/packages/react-native/Libraries/Core/setUpPerformance.js @@ -8,25 +8,8 @@ * @format */ -import setUpPerformanceModern from '../../src/private/setup/setUpPerformanceModern'; -import NativePerformance from '../../src/private/webapis/performance/specs/NativePerformance'; +// Kept as an alias of the internal `setUpPerformance` module for external +// consumers that import this path directly. +import setUpPerformance from '../../src/private/setup/setUpPerformance'; -// In case if the native implementation of the Performance API is available, use it, -// otherwise fall back to the legacy/default one, which only defines 'Performance.now()' -if (NativePerformance) { - setUpPerformanceModern(); -} else { - if (!global.performance) { - // $FlowExpectedError[cannot-write] - global.performance = { - mark: () => {}, - clearMarks: () => {}, - measure: () => {}, - clearMeasures: () => {}, - now: () => { - const performanceNow = global.nativePerformanceNow || Date.now; - return performanceNow(); - }, - }; - } -} +setUpPerformance(); diff --git a/packages/react-native/src/private/setup/setUpDefaultReactNativeEnvironment.js b/packages/react-native/src/private/setup/setUpDefaultReactNativeEnvironment.js index eb61a6644345..6bd27c4cc3d1 100644 --- a/packages/react-native/src/private/setup/setUpDefaultReactNativeEnvironment.js +++ b/packages/react-native/src/private/setup/setUpDefaultReactNativeEnvironment.js @@ -10,7 +10,7 @@ let initialized = false; -export default function setUpDefaltReactNativeEnvironment( +export default function setUpDefaultReactNativeEnvironment( enableDeveloperTools: boolean = true, ) { if (initialized) { @@ -21,7 +21,7 @@ export default function setUpDefaltReactNativeEnvironment( require('../../../Libraries/Core/setUpGlobals'); require('./setUpDOM').default(); - require('../../../Libraries/Core/setUpPerformance'); + require('./setUpPerformance').default(); require('../../../Libraries/Core/polyfillPromise'); require('../../../Libraries/Core/setUpTimers'); if (__DEV__ && enableDeveloperTools) { diff --git a/packages/react-native/src/private/setup/setUpPerformanceModern.js b/packages/react-native/src/private/setup/setUpPerformance.js similarity index 97% rename from packages/react-native/src/private/setup/setUpPerformanceModern.js rename to packages/react-native/src/private/setup/setUpPerformance.js index 22a7ca135043..747b92f5f577 100644 --- a/packages/react-native/src/private/setup/setUpPerformanceModern.js +++ b/packages/react-native/src/private/setup/setUpPerformance.js @@ -12,7 +12,7 @@ import {polyfillGlobal} from '../../../Libraries/Utilities/PolyfillFunctions'; let initialized = false; -export default function setUpPerformanceModern() { +export default function setUpPerformance() { if (initialized) { return; } diff --git a/packages/react-native/src/private/webapis/performance/EventTiming.js b/packages/react-native/src/private/webapis/performance/EventTiming.js index c175f8592f18..713964ea4f37 100644 --- a/packages/react-native/src/private/webapis/performance/EventTiming.js +++ b/packages/react-native/src/private/webapis/performance/EventTiming.js @@ -16,10 +16,7 @@ import type { } from './PerformanceEntry'; import {PerformanceEntry} from './PerformanceEntry'; -import MaybeNativePerformance from './specs/NativePerformance'; -import nullthrows from 'nullthrows'; - -const NativePerformance = nullthrows(MaybeNativePerformance); +import NativePerformance from './specs/NativePerformance'; export type PerformanceEventTimingJSON = { ...PerformanceEntryJSON, diff --git a/packages/react-native/src/private/webapis/performance/Performance.js b/packages/react-native/src/private/webapis/performance/Performance.js index 6a492064fb43..e6f544475d3a 100644 --- a/packages/react-native/src/private/webapis/performance/Performance.js +++ b/packages/react-native/src/private/webapis/performance/Performance.js @@ -29,12 +29,10 @@ import { performanceEntryTypeToRaw, rawToPerformanceEntry, } from './internals/RawPerformanceEntry'; -import {getCurrentTimeStamp} from './internals/Utilities'; import MemoryInfo from './MemoryInfo'; import ReactNativeStartupTiming from './ReactNativeStartupTiming'; -import MaybeNativePerformance from './specs/NativePerformance'; +import NativePerformance from './specs/NativePerformance'; import {PerformanceMark, PerformanceMeasure} from './UserTiming'; -import nullthrows from 'nullthrows'; export type PerformanceMeasureOptions = | Readonly<{ @@ -56,13 +54,8 @@ export type PerformanceMeasureOptions = const ENTRY_TYPES_AVAILABLE_FROM_TIMELINE: ReadonlyArray = ['mark', 'measure']; -const NativePerformance = nullthrows(MaybeNativePerformance); - -const cachedReportMark = NativePerformance.reportMark; -const cachedReportMeasure = NativePerformance.reportMeasure; -const cachedGetMarkTime = NativePerformance.getMarkTime; -const cachedNativeClearMarks = NativePerformance.clearMarks; -const cachedNativeClearMeasures = NativePerformance.clearMeasures; +const {now, reportMark, reportMeasure, getMarkTime, clearMarks, clearMeasures} = + NativePerformance; let cachedTimeOrigin: ?DOMHighResTimeStamp; const MARK_OPTIONS_REUSABLE_OBJECT: PerformanceMarkOptions = { @@ -78,7 +71,7 @@ const MEASURE_OPTIONS_REUSABLE_OBJECT: PerformanceMeasureInit = { }; const getMarkTimeForMeasure = (markName: string): number => { - const markTime = cachedGetMarkTime(markName); + const markTime = getMarkTime(markName); if (markTime == null) { throw new DOMException( `Failed to execute 'measure' on 'Performance': The mark '${markName}' does not exist.`, @@ -147,12 +140,7 @@ export default class Performance { */ get timeOrigin(): DOMHighResTimeStamp { if (cachedTimeOrigin == null) { - if (NativePerformance.timeOrigin) { - cachedTimeOrigin = NativePerformance?.timeOrigin(); - } else { - // Very naive polyfill. - cachedTimeOrigin = Date.now() - getCurrentTimeStamp(); - } + cachedTimeOrigin = NativePerformance.timeOrigin(); } return cachedTimeOrigin; @@ -202,7 +190,7 @@ export default class Performance { ); } } else { - resolvedStartTime = getCurrentTimeStamp(); + resolvedStartTime = now(); } if (detail !== undefined) { @@ -219,13 +207,13 @@ export default class Performance { MARK_OPTIONS_REUSABLE_OBJECT, ); - cachedReportMark(resolvedMarkName, resolvedStartTime, entry); + reportMark(resolvedMarkName, resolvedStartTime, entry); return entry; } clearMarks(markName?: string): void { - cachedNativeClearMarks(markName); + clearMarks(markName); } measure( @@ -347,7 +335,7 @@ export default class Performance { ) { resolvedDuration = resolvedEndTime - resolvedStartTime; } else { - resolvedDuration = getCurrentTimeStamp() - resolvedStartTime; + resolvedDuration = now() - resolvedStartTime; } } @@ -364,7 +352,7 @@ export default class Performance { resolvedDuration = getMarkTimeForMeasure(endMark) - resolvedStartTime; } else { - resolvedDuration = getCurrentTimeStamp() - resolvedStartTime; + resolvedDuration = now() - resolvedStartTime; } break; } @@ -375,7 +363,7 @@ export default class Performance { resolvedDuration = getMarkTimeForMeasure(endMark) - resolvedStartTime; } else { - resolvedDuration = getCurrentTimeStamp() - resolvedStartTime; + resolvedDuration = now() - resolvedStartTime; } } } @@ -385,7 +373,7 @@ export default class Performance { if (endMark !== undefined) { resolvedDuration = getMarkTimeForMeasure(endMark) - resolvedStartTime; } else { - resolvedDuration = getCurrentTimeStamp() - resolvedStartTime; + resolvedDuration = now() - resolvedStartTime; } } @@ -400,7 +388,7 @@ export default class Performance { const entry = new PerformanceMeasure(MEASURE_OPTIONS_REUSABLE_OBJECT); - cachedReportMeasure( + reportMeasure( resolvedMeasureName, resolvedStartTime, resolvedDuration, @@ -411,14 +399,14 @@ export default class Performance { } clearMeasures(measureName?: string): void { - cachedNativeClearMeasures(measureName); + clearMeasures(measureName); } /** * Returns a double, measured in milliseconds. * https://developer.mozilla.org/en-US/docs/Web/API/Performance/now */ - now: () => DOMHighResTimeStamp = getCurrentTimeStamp; + now: () => DOMHighResTimeStamp = now; /** * An extension that allows to get back to JS all currently logged marks/measures diff --git a/packages/react-native/src/private/webapis/performance/PerformanceObserver.js b/packages/react-native/src/private/webapis/performance/PerformanceObserver.js index b66e7f406614..e4d899a3cb72 100644 --- a/packages/react-native/src/private/webapis/performance/PerformanceObserver.js +++ b/packages/react-native/src/private/webapis/performance/PerformanceObserver.js @@ -21,13 +21,11 @@ import { rawToPerformanceEntry, rawToPerformanceEntryType, } from './internals/RawPerformanceEntry'; -import MaybeNativePerformance from './specs/NativePerformance'; +import NativePerformance from './specs/NativePerformance'; import nullthrows from 'nullthrows'; export {PerformanceEntry} from './PerformanceEntry'; -const NativePerformance = nullthrows(MaybeNativePerformance); - export class PerformanceObserverEntryList { #entries: PerformanceEntryList; diff --git a/packages/react-native/src/private/webapis/performance/UserTiming.js b/packages/react-native/src/private/webapis/performance/UserTiming.js index ff8786083194..f07b48c763bb 100644 --- a/packages/react-native/src/private/webapis/performance/UserTiming.js +++ b/packages/react-native/src/private/webapis/performance/UserTiming.js @@ -18,8 +18,10 @@ import type { ExtensionTrackEntryPayload, } from './UserTimingExtensibility'; -import {getCurrentTimeStamp} from './internals/Utilities'; import {PerformanceEntry} from './PerformanceEntry'; +import NativePerformance from './specs/NativePerformance'; + +const {now} = NativePerformance; export type DetailType = | unknown @@ -47,7 +49,7 @@ class PerformanceMarkTemplate extends PerformanceEntry { constructor(markName: string, markOptions?: PerformanceMarkOptions) { super('mark', { name: markName, - startTime: markOptions?.startTime ?? getCurrentTimeStamp(), + startTime: markOptions?.startTime ?? now(), duration: 0, }); @@ -73,7 +75,7 @@ export const PerformanceMark: typeof PerformanceMarkTemplate = ) { this.__entryType = 'mark'; this.__name = markName; - this.__startTime = markOptions?.startTime ?? getCurrentTimeStamp(); + this.__startTime = markOptions?.startTime ?? now(); this.__duration = 0; this.__detail = markOptions?.detail ?? null; diff --git a/packages/react-native/src/private/webapis/performance/internals/Utilities.js b/packages/react-native/src/private/webapis/performance/internals/Utilities.js deleted file mode 100644 index 929afbe51282..000000000000 --- a/packages/react-native/src/private/webapis/performance/internals/Utilities.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict - * @format - */ - -import warnOnce from '../../../../../Libraries/Utilities/warnOnce'; -import NativePerformance from '../specs/NativePerformance'; - -export function warnNoNativePerformance() { - warnOnce( - 'missing-native-performance', - 'Missing native implementation of Performance', - ); -} - -declare var global: { - // This value is defined directly via JSI, if available. - readonly nativePerformanceNow?: ?() => number, -}; - -export const getCurrentTimeStamp: () => DOMHighResTimeStamp = - NativePerformance?.now ?? global.nativePerformanceNow ?? (() => Date.now()); diff --git a/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js b/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js index 11e73d19d531..a3c4284e6baa 100644 --- a/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js +++ b/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js @@ -57,7 +57,7 @@ export type PerformanceObserverInit = { export interface Spec extends TurboModule { readonly now: () => number; - readonly timeOrigin?: () => number; + readonly timeOrigin: () => number; readonly reportMark: ( name: string, @@ -107,4 +107,6 @@ export interface Spec extends TurboModule { readonly clearEventCountsForTesting: () => void; } -export default TurboModuleRegistry.get('NativePerformanceCxx') as ?Spec; +export default TurboModuleRegistry.getEnforcing( + 'NativePerformanceCxx', +) as Spec;