Small refactor of performance API (#52558)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52558

Changelog: [internal]

Small refactors for `$ReadOnly`, move `getCurrentTimeStamp` to utils so it can be reused, etc.

Reviewed By: hoxyq

Differential Revision: D78013570

fbshipit-source-id: f73d119f22dd4dc9aaa5efef76a1156821ecd8de
This commit is contained in:
Rubén Norte
2025-07-11 05:37:31 -07:00
committed by Facebook GitHub Bot
parent acd07c7e1c
commit 5e0eb0a17c
3 changed files with 33 additions and 28 deletions
@@ -25,31 +25,26 @@ import {
performanceEntryTypeToRaw,
rawToPerformanceEntry,
} from './internals/RawPerformanceEntry';
import {warnNoNativePerformance} from './internals/Utilities';
import {
getCurrentTimeStamp,
warnNoNativePerformance,
} from './internals/Utilities';
import MemoryInfo from './MemoryInfo';
import ReactNativeStartupTiming from './ReactNativeStartupTiming';
import NativePerformance from './specs/NativePerformance';
import {PerformanceMark, PerformanceMeasure} from './UserTiming';
declare var global: {
// This value is defined directly via JSI, if available.
+nativePerformanceNow?: ?() => number,
};
const getCurrentTimeStamp: () => DOMHighResTimeStamp =
NativePerformance?.now ?? global.nativePerformanceNow ?? (() => Date.now());
export type PerformanceMeasureOptions =
| {
| $ReadOnly<{
detail?: DetailType,
start?: DOMHighResTimeStamp | string,
duration?: DOMHighResTimeStamp,
}
| {
}>
| $ReadOnly<{
detail?: DetailType,
start?: DOMHighResTimeStamp | string,
end?: DOMHighResTimeStamp | string,
};
}>;
const ENTRY_TYPES_AVAILABLE_FROM_TIMELINE: $ReadOnlyArray<PerformanceEntryType> =
['mark', 'measure'];
@@ -155,7 +150,7 @@ export default class Performance {
);
} else {
warnNoNativePerformance();
computedStartTime = performance.now();
computedStartTime = getCurrentTimeStamp();
}
return new PerformanceMark(resolvedMarkName, {
@@ -12,44 +12,45 @@
import type {DOMHighResTimeStamp} from './PerformanceEntry';
import {getCurrentTimeStamp} from './internals/Utilities';
import {PerformanceEntry} from './PerformanceEntry';
export type DetailType = mixed;
export type PerformanceMarkOptions = {
export type PerformanceMarkOptions = $ReadOnly<{
detail?: DetailType,
startTime?: DOMHighResTimeStamp,
};
}>;
export type TimeStampOrName = DOMHighResTimeStamp | string;
export type PerformanceMeasureInit = {
export type PerformanceMeasureInit = $ReadOnly<{
detail?: DetailType,
startTime: DOMHighResTimeStamp,
duration: DOMHighResTimeStamp,
};
}>;
class PerformanceMarkTemplate extends PerformanceEntry {
// We don't use private fields because they're significantly slower to
// initialize on construction and to access.
_detail: DetailType;
__detail: DetailType;
// This constructor isn't really used. See `PerformanceMark` below.
constructor(markName: string, markOptions?: PerformanceMarkOptions) {
super({
name: markName,
entryType: 'mark',
startTime: markOptions?.startTime ?? performance.now(),
startTime: markOptions?.startTime ?? getCurrentTimeStamp(),
duration: 0,
});
if (markOptions) {
this._detail = markOptions.detail;
this.__detail = markOptions.detail;
}
}
get detail(): DetailType {
return this._detail;
return this.__detail;
}
}
@@ -67,11 +68,11 @@ export const PerformanceMark: typeof PerformanceMarkTemplate =
) {
this.__name = markName;
this.__entryType = 'mark';
this.__startTime = markOptions?.startTime ?? performance.now();
this.__startTime = markOptions?.startTime ?? getCurrentTimeStamp();
this.__duration = 0;
if (markOptions) {
this._detail = markOptions.detail;
this.__detail = markOptions.detail;
}
};
@@ -81,7 +82,7 @@ PerformanceMark.prototype = PerformanceMarkTemplate.prototype;
class PerformanceMeasureTemplate extends PerformanceEntry {
// We don't use private fields because they're significantly slower to
// initialize on construction and to access.
_detail: DetailType;
__detail: DetailType;
// This constructor isn't really used. See `PerformanceMeasure` below.
constructor(measureName: string, measureOptions: PerformanceMeasureInit) {
@@ -93,12 +94,12 @@ class PerformanceMeasureTemplate extends PerformanceEntry {
});
if (measureOptions) {
this._detail = measureOptions.detail;
this.__detail = measureOptions.detail;
}
}
get detail(): DetailType {
return this._detail;
return this.__detail;
}
}
@@ -116,7 +117,7 @@ export const PerformanceMeasure: typeof PerformanceMeasureTemplate =
this.__duration = measureOptions.duration;
if (measureOptions) {
this._detail = measureOptions.detail;
this.__detail = measureOptions.detail;
}
};
@@ -9,6 +9,7 @@
*/
import warnOnce from '../../../../../Libraries/Utilities/warnOnce';
import NativePerformance from '../specs/NativePerformance';
export function warnNoNativePerformance() {
warnOnce(
@@ -16,3 +17,11 @@ export function warnNoNativePerformance() {
'Missing native implementation of Performance',
);
}
declare var global: {
// This value is defined directly via JSI, if available.
+nativePerformanceNow?: ?() => number,
};
export const getCurrentTimeStamp: () => DOMHighResTimeStamp =
NativePerformance?.now ?? global.nativePerformanceNow ?? (() => Date.now());