diff --git a/packages/react-native/src/private/webapis/performance/EventTiming.js b/packages/react-native/src/private/webapis/performance/EventTiming.js index 3f99141e223..95657a3b042 100644 --- a/packages/react-native/src/private/webapis/performance/EventTiming.js +++ b/packages/react-native/src/private/webapis/performance/EventTiming.js @@ -9,9 +9,9 @@ */ // flowlint unsafe-getters-setters:off - import type { DOMHighResTimeStamp, + PerformanceEntryInit, PerformanceEntryJSON, } from './PerformanceEntry'; @@ -29,25 +29,20 @@ export type PerformanceEventTimingJSON = { ... }; +export interface PerformanceEventTimingInit extends PerformanceEntryInit { + +processingStart?: DOMHighResTimeStamp; + +processingEnd?: DOMHighResTimeStamp; + +interactionId?: number; +} + export class PerformanceEventTiming extends PerformanceEntry { #processingStart: DOMHighResTimeStamp; #processingEnd: DOMHighResTimeStamp; #interactionId: number; - constructor(init: { - name: string, - startTime?: DOMHighResTimeStamp, - duration?: DOMHighResTimeStamp, - processingStart?: DOMHighResTimeStamp, - processingEnd?: DOMHighResTimeStamp, - interactionId?: number, - }) { - super({ - name: init.name, - entryType: 'event', - startTime: init.startTime ?? 0, - duration: init.duration ?? 0, - }); + constructor(init: PerformanceEventTimingInit) { + super('event', init); + this.#processingStart = init.processingStart ?? 0; this.#processingEnd = init.processingEnd ?? 0; this.#interactionId = init.interactionId ?? 0; diff --git a/packages/react-native/src/private/webapis/performance/LongTasks.js b/packages/react-native/src/private/webapis/performance/LongTasks.js index 4c745db150e..9c27419dd07 100644 --- a/packages/react-native/src/private/webapis/performance/LongTasks.js +++ b/packages/react-native/src/private/webapis/performance/LongTasks.js @@ -9,8 +9,10 @@ */ // flowlint unsafe-getters-setters:off - -import type {PerformanceEntryJSON} from './PerformanceEntry'; +import type { + PerformanceEntryInit, + PerformanceEntryJSON, +} from './PerformanceEntry'; import {PerformanceEntry} from './PerformanceEntry'; @@ -25,7 +27,13 @@ export class TaskAttributionTiming extends PerformanceEntry {} const EMPTY_ATTRIBUTION: $ReadOnlyArray = Object.preventExtensions([]); +export interface PerformanceLongTaskTimingInit extends PerformanceEntryInit {} + export class PerformanceLongTaskTiming extends PerformanceEntry { + constructor(init: PerformanceEntryInit) { + super('longtask', init); + } + get attribution(): $ReadOnlyArray { return EMPTY_ATTRIBUTION; } diff --git a/packages/react-native/src/private/webapis/performance/Performance.js b/packages/react-native/src/private/webapis/performance/Performance.js index 65c66dd2359..6cd2fd5b0a7 100644 --- a/packages/react-native/src/private/webapis/performance/Performance.js +++ b/packages/react-native/src/private/webapis/performance/Performance.js @@ -64,12 +64,13 @@ const cachedGetMarkTime = NativePerformance.getMarkTime; const cachedNativeClearMarks = NativePerformance.clearMarks; const cachedNativeClearMeasures = NativePerformance.clearMeasures; -const MARK_OPTIONS_REUSABLE_OBJECT: {...PerformanceMarkOptions} = { +const MARK_OPTIONS_REUSABLE_OBJECT: PerformanceMarkOptions = { startTime: 0, detail: undefined, }; -const MEASURE_OPTIONS_REUSABLE_OBJECT: {...PerformanceMeasureInit} = { +const MEASURE_OPTIONS_REUSABLE_OBJECT: PerformanceMeasureInit = { + name: '', startTime: 0, duration: 0, detail: undefined, @@ -189,7 +190,9 @@ export default class Performance { resolvedDetail = structuredClone(detail); } + // $FlowExpectedError[cannot-write] MARK_OPTIONS_REUSABLE_OBJECT.startTime = resolvedStartTime; + // $FlowExpectedError[cannot-write] MARK_OPTIONS_REUSABLE_OBJECT.detail = resolvedDetail; const entry = new PerformanceMark( @@ -367,14 +370,16 @@ export default class Performance { } } + // $FlowExpectedError[cannot-write] + MEASURE_OPTIONS_REUSABLE_OBJECT.name = resolvedMeasureName; + // $FlowExpectedError[cannot-write] MEASURE_OPTIONS_REUSABLE_OBJECT.startTime = resolvedStartTime; + // $FlowExpectedError[cannot-write] MEASURE_OPTIONS_REUSABLE_OBJECT.duration = resolvedDuration; + // $FlowExpectedError[cannot-write] MEASURE_OPTIONS_REUSABLE_OBJECT.detail = resolvedDetail; - const entry = new PerformanceMeasure( - resolvedMeasureName, - MEASURE_OPTIONS_REUSABLE_OBJECT, - ); + const entry = new PerformanceMeasure(MEASURE_OPTIONS_REUSABLE_OBJECT); cachedReportMeasure( resolvedMeasureName, diff --git a/packages/react-native/src/private/webapis/performance/PerformanceEntry.js b/packages/react-native/src/private/webapis/performance/PerformanceEntry.js index f2ddfceda55..e5184c28399 100644 --- a/packages/react-native/src/private/webapis/performance/PerformanceEntry.js +++ b/packages/react-native/src/private/webapis/performance/PerformanceEntry.js @@ -28,24 +28,25 @@ export type PerformanceEntryJSON = { ... }; +export interface PerformanceEntryInit { + +name: string; + +startTime: DOMHighResTimeStamp; + +duration: DOMHighResTimeStamp; +} + export class PerformanceEntry { // We don't use private fields because they're significantly slower to // initialize on construction and to access. // We also need these to be protected so they can be initialized in subclasses // where we avoid calling `super()` for performance reasons. - __name: string; __entryType: PerformanceEntryType; + __name: string; __startTime: DOMHighResTimeStamp; __duration: DOMHighResTimeStamp; - constructor(init: { - name: string, - entryType: PerformanceEntryType, - startTime: DOMHighResTimeStamp, - duration: DOMHighResTimeStamp, - }) { + constructor(entryType: PerformanceEntryType, init: PerformanceEntryInit) { + this.__entryType = entryType; this.__name = init.name; - this.__entryType = init.entryType; this.__startTime = init.startTime; this.__duration = init.duration; } diff --git a/packages/react-native/src/private/webapis/performance/ResourceTiming.js b/packages/react-native/src/private/webapis/performance/ResourceTiming.js index 0f02887250b..65440e00a8a 100644 --- a/packages/react-native/src/private/webapis/performance/ResourceTiming.js +++ b/packages/react-native/src/private/webapis/performance/ResourceTiming.js @@ -29,6 +29,19 @@ export type PerformanceResourceTimingJSON = { ... }; +export interface PerformanceResourceTimingInit { + +name: string; + +startTime: DOMHighResTimeStamp; + +duration: DOMHighResTimeStamp; + +fetchStart: DOMHighResTimeStamp; + +requestStart: DOMHighResTimeStamp; + +connectStart: DOMHighResTimeStamp; + +connectEnd: DOMHighResTimeStamp; + +responseStart: DOMHighResTimeStamp; + +responseEnd: DOMHighResTimeStamp; + +responseStatus?: number; +} + export class PerformanceResourceTiming extends PerformanceEntry { #fetchStart: DOMHighResTimeStamp; #requestStart: DOMHighResTimeStamp; @@ -38,24 +51,9 @@ export class PerformanceResourceTiming extends PerformanceEntry { #responseEnd: DOMHighResTimeStamp; #responseStatus: ?number; - constructor(init: { - name: string, - startTime: DOMHighResTimeStamp, - duration: DOMHighResTimeStamp, - fetchStart: DOMHighResTimeStamp, - requestStart: DOMHighResTimeStamp, - connectStart: DOMHighResTimeStamp, - connectEnd: DOMHighResTimeStamp, - responseStart: DOMHighResTimeStamp, - responseEnd: DOMHighResTimeStamp, - responseStatus?: number, - }) { - super({ - name: init.name, - entryType: 'resource', - startTime: init.startTime, - duration: init.duration, - }); + constructor(init: PerformanceResourceTimingInit) { + super('resource', init); + this.#fetchStart = init.fetchStart; this.#requestStart = init.requestStart; this.#connectStart = init.connectStart; diff --git a/packages/react-native/src/private/webapis/performance/UserTiming.js b/packages/react-native/src/private/webapis/performance/UserTiming.js index c52df24e92b..910f6128d5d 100644 --- a/packages/react-native/src/private/webapis/performance/UserTiming.js +++ b/packages/react-native/src/private/webapis/performance/UserTiming.js @@ -9,8 +9,10 @@ */ // flowlint unsafe-getters-setters:off - -import type {DOMHighResTimeStamp} from './PerformanceEntry'; +import type { + DOMHighResTimeStamp, + PerformanceEntryInit, +} from './PerformanceEntry'; import type { ExtensionMarkerPayload, ExtensionTrackEntryPayload, @@ -25,18 +27,16 @@ export type DetailType = // but we'll use it as documentation for how to use the extensibility API. | {devtools?: ExtensionMarkerPayload | ExtensionTrackEntryPayload, ...}; -export type PerformanceMarkOptions = $ReadOnly<{ - detail?: DetailType, - startTime?: DOMHighResTimeStamp, -}>; +export interface PerformanceMarkOptions { + +detail?: DetailType; + +startTime?: DOMHighResTimeStamp; +} export type TimeStampOrName = DOMHighResTimeStamp | string; -export type PerformanceMeasureInit = $ReadOnly<{ - detail?: DetailType, - startTime: DOMHighResTimeStamp, - duration: DOMHighResTimeStamp, -}>; +export interface PerformanceMeasureInit extends PerformanceEntryInit { + +detail?: DetailType; +} class PerformanceMarkTemplate extends PerformanceEntry { // We don't use private fields because they're significantly slower to @@ -45,9 +45,8 @@ class PerformanceMarkTemplate extends PerformanceEntry { // This constructor isn't really used. See `PerformanceMark` below. constructor(markName: string, markOptions?: PerformanceMarkOptions) { - super({ + super('mark', { name: markName, - entryType: 'mark', startTime: markOptions?.startTime ?? getCurrentTimeStamp(), duration: 0, }); @@ -72,8 +71,8 @@ export const PerformanceMark: typeof PerformanceMarkTemplate = markName: string, markOptions?: PerformanceMarkOptions, ) { - this.__name = markName; this.__entryType = 'mark'; + this.__name = markName; this.__startTime = markOptions?.startTime ?? getCurrentTimeStamp(); this.__duration = 0; @@ -89,15 +88,10 @@ class PerformanceMeasureTemplate extends PerformanceEntry { __detail: DetailType; // This constructor isn't really used. See `PerformanceMeasure` below. - constructor(measureName: string, measureOptions: PerformanceMeasureInit) { - super({ - name: measureName, - entryType: 'measure', - startTime: measureOptions.startTime, - duration: measureOptions.duration, - }); + constructor(init: PerformanceMeasureInit) { + super('measure', init); - this.__detail = measureOptions?.detail ?? null; + this.__detail = init?.detail ?? null; } get detail(): DetailType { @@ -110,15 +104,14 @@ export const PerformanceMeasure: typeof PerformanceMeasureTemplate = // $FlowExpectedError[incompatible-type] function PerformanceMeasure( this: PerformanceMeasureTemplate, - measureName: string, - measureOptions: PerformanceMeasureInit, + init: PerformanceMeasureInit, ) { - this.__name = measureName; this.__entryType = 'measure'; - this.__startTime = measureOptions.startTime; - this.__duration = measureOptions.duration; + this.__name = init.name; + this.__startTime = init.startTime; + this.__duration = init.duration; - this.__detail = measureOptions.detail ?? null; + this.__detail = init.detail ?? null; }; // $FlowExpectedError[prop-missing] diff --git a/packages/react-native/src/private/webapis/performance/internals/RawPerformanceEntry.js b/packages/react-native/src/private/webapis/performance/internals/RawPerformanceEntry.js index 900541b4bba..40854b834ba 100644 --- a/packages/react-native/src/private/webapis/performance/internals/RawPerformanceEntry.js +++ b/packages/react-native/src/private/webapis/performance/internals/RawPerformanceEntry.js @@ -44,7 +44,6 @@ export function rawToPerformanceEntry( case RawPerformanceEntryTypeValues.LONGTASK: return new PerformanceLongTaskTiming({ name: entry.name, - entryType: rawToPerformanceEntryType(entry.entryType), startTime: entry.startTime, duration: entry.duration, }); @@ -53,7 +52,8 @@ export function rawToPerformanceEntry( startTime: entry.startTime, }); case RawPerformanceEntryTypeValues.MEASURE: - return new PerformanceMeasure(entry.name, { + return new PerformanceMeasure({ + name: entry.name, startTime: entry.startTime, duration: entry.duration, }); @@ -71,9 +71,8 @@ export function rawToPerformanceEntry( responseStatus: entry.responseStatus, }); default: - return new PerformanceEntry({ + return new PerformanceEntry(rawToPerformanceEntryType(entry.entryType), { name: entry.name, - entryType: rawToPerformanceEntryType(entry.entryType), startTime: entry.startTime, duration: entry.duration, });