diff --git a/packages/react-native/Libraries/Core/setUpPerformanceObserver.js b/packages/react-native/Libraries/Core/setUpPerformanceObserver.js index 47ed15546c2a..f182ebc2e37c 100644 --- a/packages/react-native/Libraries/Core/setUpPerformanceObserver.js +++ b/packages/react-native/Libraries/Core/setUpPerformanceObserver.js @@ -16,3 +16,51 @@ polyfillGlobal( require('../../src/private/webapis/performance/PerformanceObserver') .default, ); + +polyfillGlobal( + 'PerformanceObserverEntryList', + () => + require('../../src/private/webapis/performance/PerformanceObserver') + .PerformanceObserverEntryList, +); + +polyfillGlobal( + 'PerformanceEntry', + () => + require('../../src/private/webapis/performance/PerformanceEntry') + .PerformanceEntry, +); + +polyfillGlobal( + 'PerformanceMark', + () => + require('../../src/private/webapis/performance/UserTiming').PerformanceMark, +); + +polyfillGlobal( + 'PerformanceMeasure', + () => + require('../../src/private/webapis/performance/UserTiming') + .PerformanceMeasure, +); + +polyfillGlobal( + 'PerformanceEventTiming', + () => + require('../../src/private/webapis/performance/EventTiming') + .PerformanceEventTiming, +); + +polyfillGlobal( + 'TaskAttributionTiming', + () => + require('../../src/private/webapis/performance/LongTasks') + .TaskAttributionTiming, +); + +polyfillGlobal( + 'PerformanceLongTaskTiming', + () => + require('../../src/private/webapis/performance/LongTasks') + .PerformanceLongTaskTiming, +); diff --git a/packages/react-native/src/private/webapis/performance/EventCounts.js b/packages/react-native/src/private/webapis/performance/EventTiming.js similarity index 56% rename from packages/react-native/src/private/webapis/performance/EventCounts.js rename to packages/react-native/src/private/webapis/performance/EventTiming.js index 682ef5557072..110689a06011 100644 --- a/packages/react-native/src/private/webapis/performance/EventCounts.js +++ b/packages/react-native/src/private/webapis/performance/EventTiming.js @@ -4,13 +4,75 @@ * 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 + * @flow strict */ +// flowlint unsafe-getters-setters:off + +import type { + DOMHighResTimeStamp, + PerformanceEntryJSON, +} from './PerformanceEntry'; + +import {PerformanceEntry} from './PerformanceEntry'; import {warnNoNativePerformanceObserver} from './PerformanceObserver'; import NativePerformanceObserver from './specs/NativePerformanceObserver'; +export type PerformanceEventTimingJSON = { + ...PerformanceEntryJSON, + 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, + }); + this.#processingStart = init.processingStart ?? 0; + this.#processingEnd = init.processingEnd ?? 0; + this.#interactionId = init.interactionId ?? 0; + } + + get processingStart(): DOMHighResTimeStamp { + return this.#processingStart; + } + + get processingEnd(): DOMHighResTimeStamp { + return this.#processingEnd; + } + + get interactionId(): number { + return this.#interactionId; + } + + toJSON(): PerformanceEventTimingJSON { + return { + ...super.toJSON(), + processingStart: this.#processingStart, + processingEnd: this.#processingEnd, + interactionId: this.#interactionId, + }; + } +} + type EventCountsForEachCallbackType = | (() => void) | ((value: number) => void) @@ -41,13 +103,13 @@ function getCachedEventCounts(): Map { }); return cachedEventCounts ?? new Map(); } + /** * Implementation of the EventCounts Web Performance API * corresponding to the standard in * https://www.w3.org/TR/event-timing/#eventcounts */ -export default class EventCounts { - // flowlint unsafe-getters-setters:off +export class EventCounts { get size(): number { return getCachedEventCounts().size; } diff --git a/packages/react-native/src/private/webapis/performance/LongTasks.js b/packages/react-native/src/private/webapis/performance/LongTasks.js new file mode 100644 index 000000000000..20164b7fc32d --- /dev/null +++ b/packages/react-native/src/private/webapis/performance/LongTasks.js @@ -0,0 +1,39 @@ +/** + * 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. + * + * @format + * @flow strict + */ + +// flowlint unsafe-getters-setters:off + +import type {PerformanceEntryJSON} from './PerformanceEntry'; + +import {PerformanceEntry} from './PerformanceEntry'; + +export type PerformanceLongTaskTimingJSON = { + ...PerformanceEntryJSON, + attribution: $ReadOnlyArray, + ... +}; + +export class TaskAttributionTiming extends PerformanceEntry {} + +const EMPTY_ATTRIBUTION: $ReadOnlyArray = + Object.preventExtensions([]); + +export class PerformanceLongTaskTiming extends PerformanceEntry { + get attribution(): $ReadOnlyArray { + return EMPTY_ATTRIBUTION; + } + + toJSON(): PerformanceLongTaskTimingJSON { + return { + ...super.toJSON(), + attribution: this.attribution, + }; + } +} diff --git a/packages/react-native/src/private/webapis/performance/Performance.js b/packages/react-native/src/private/webapis/performance/Performance.js index dbadef33aa47..5861d3582803 100644 --- a/packages/react-native/src/private/webapis/performance/Performance.js +++ b/packages/react-native/src/private/webapis/performance/Performance.js @@ -10,15 +10,15 @@ // flowlint unsafe-getters-setters:off -import type {HighResTimeStamp, PerformanceEntryType} from './PerformanceEntry'; -import type {PerformanceEntryList} from './PerformanceObserver'; import type { - PerformanceMarkOptions, - PerformanceMeasureOptions, -} from './UserTiming'; + DOMHighResTimeStamp, + PerformanceEntryType, +} from './PerformanceEntry'; +import type {PerformanceEntryList} from './PerformanceObserver'; +import type {DetailType, PerformanceMarkOptions} from './UserTiming'; import warnOnce from '../../../../Libraries/Utilities/warnOnce'; -import EventCounts from './EventCounts'; +import {EventCounts} from './EventTiming'; import MemoryInfo from './MemoryInfo'; import {ALWAYS_LOGGED_ENTRY_TYPES} from './PerformanceEntry'; import {warnNoNativePerformanceObserver} from './PerformanceObserver'; @@ -37,7 +37,7 @@ declare var global: { +nativePerformanceNow?: ?() => number, }; -const getCurrentTimeStamp: () => HighResTimeStamp = +const getCurrentTimeStamp: () => DOMHighResTimeStamp = NativePerformance?.now ?? global.nativePerformanceNow ?? (() => Date.now()); // We want some of the performance entry types to be always logged, @@ -58,6 +58,13 @@ function warnNoNativePerformance() { ); } +export type PerformanceMeasureOptions = { + detail?: DetailType, + start?: DOMHighResTimeStamp, + duration?: DOMHighResTimeStamp, + end?: DOMHighResTimeStamp, +}; + /** * Partial implementation of the Performance interface for RN, * corresponding to the standard in @@ -195,7 +202,13 @@ export default class Performance { duration = options.duration ?? duration; } - const measure = new PerformanceMeasure(measureName, options); + const measure = new PerformanceMeasure(measureName, { + // FIXME(T196011255): this is incorrect, as we're only assigning the + // start/end if they're specified as a number, but not if they're + // specified as previous mark names. + startTime, + duration, + }); if (NativePerformance?.measure) { NativePerformance.measure( @@ -229,7 +242,7 @@ export default class Performance { * Returns a double, measured in milliseconds. * https://developer.mozilla.org/en-US/docs/Web/API/Performance/now */ - now(): HighResTimeStamp { + now(): DOMHighResTimeStamp { return getCurrentTimeStamp(); } diff --git a/packages/react-native/src/private/webapis/performance/PerformanceEntry.js b/packages/react-native/src/private/webapis/performance/PerformanceEntry.js index 62c0b0226650..4eca72298477 100644 --- a/packages/react-native/src/private/webapis/performance/PerformanceEntry.js +++ b/packages/react-native/src/private/webapis/performance/PerformanceEntry.js @@ -8,14 +8,16 @@ * @flow strict */ -export type HighResTimeStamp = number; +// flowlint unsafe-getters-setters:off + +export type DOMHighResTimeStamp = number; export type PerformanceEntryType = 'mark' | 'measure' | 'event' | 'longtask'; export type PerformanceEntryJSON = { name: string, entryType: PerformanceEntryType, - startTime: HighResTimeStamp, - duration: HighResTimeStamp, + startTime: DOMHighResTimeStamp, + duration: DOMHighResTimeStamp, ... }; @@ -25,29 +27,45 @@ export const ALWAYS_LOGGED_ENTRY_TYPES: $ReadOnlyArray = [ ]; export class PerformanceEntry { - name: string; - entryType: PerformanceEntryType; - startTime: HighResTimeStamp; - duration: HighResTimeStamp; + #name: string; + #entryType: PerformanceEntryType; + #startTime: DOMHighResTimeStamp; + #duration: DOMHighResTimeStamp; constructor(init: { name: string, entryType: PerformanceEntryType, - startTime: HighResTimeStamp, - duration: HighResTimeStamp, + startTime: DOMHighResTimeStamp, + duration: DOMHighResTimeStamp, }) { - this.name = init.name; - this.entryType = init.entryType; - this.startTime = init.startTime; - this.duration = init.duration; + this.#name = init.name; + this.#entryType = init.entryType; + this.#startTime = init.startTime; + this.#duration = init.duration; + } + + get name(): string { + return this.#name; + } + + get entryType(): PerformanceEntryType { + return this.#entryType; + } + + get startTime(): DOMHighResTimeStamp { + return this.#startTime; + } + + get duration(): DOMHighResTimeStamp { + return this.#duration; } toJSON(): PerformanceEntryJSON { return { - name: this.name, - entryType: this.entryType, - startTime: this.startTime, - duration: this.duration, + name: this.#name, + entryType: this.#entryType, + startTime: this.#startTime, + duration: this.#duration, }; } } diff --git a/packages/react-native/src/private/webapis/performance/PerformanceEventTiming.js b/packages/react-native/src/private/webapis/performance/PerformanceEventTiming.js deleted file mode 100644 index 9f2fa2bfcb8f..000000000000 --- a/packages/react-native/src/private/webapis/performance/PerformanceEventTiming.js +++ /dev/null @@ -1,55 +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. - * - * @format - * @flow strict - */ - -import type {HighResTimeStamp, PerformanceEntryJSON} from './PerformanceEntry'; - -import {PerformanceEntry} from './PerformanceEntry'; - -export type PerformanceEventTimingJSON = { - ...PerformanceEntryJSON, - processingStart: HighResTimeStamp, - processingEnd: HighResTimeStamp, - interactionId: number, - ... -}; - -export default class PerformanceEventTiming extends PerformanceEntry { - processingStart: HighResTimeStamp; - processingEnd: HighResTimeStamp; - interactionId: number; - - constructor(init: { - name: string, - startTime?: HighResTimeStamp, - duration?: HighResTimeStamp, - processingStart?: HighResTimeStamp, - processingEnd?: HighResTimeStamp, - interactionId?: number, - }) { - super({ - name: init.name, - entryType: 'event', - startTime: init.startTime ?? 0, - duration: init.duration ?? 0, - }); - this.processingStart = init.processingStart ?? 0; - this.processingEnd = init.processingEnd ?? 0; - this.interactionId = init.interactionId ?? 0; - } - - toJSON(): PerformanceEventTimingJSON { - return { - ...super.toJSON(), - processingStart: this.processingStart, - processingEnd: this.processingEnd, - interactionId: this.interactionId, - }; - } -} diff --git a/packages/react-native/src/private/webapis/performance/PerformanceObserver.js b/packages/react-native/src/private/webapis/performance/PerformanceObserver.js index 7bf0c1e3ebb3..278c38e05305 100644 --- a/packages/react-native/src/private/webapis/performance/PerformanceObserver.js +++ b/packages/react-native/src/private/webapis/performance/PerformanceObserver.js @@ -8,11 +8,14 @@ * @flow strict */ -import type {HighResTimeStamp, PerformanceEntryType} from './PerformanceEntry'; +import type { + DOMHighResTimeStamp, + PerformanceEntryType, +} from './PerformanceEntry'; import warnOnce from '../../../../Libraries/Utilities/warnOnce'; +import {PerformanceEventTiming} from './EventTiming'; import {PerformanceEntry} from './PerformanceEntry'; -import PerformanceEventTiming from './PerformanceEventTiming'; import { performanceEntryTypeToRaw, rawToPerformanceEntry, @@ -66,13 +69,13 @@ export type PerformanceObserverInit = } | { type: PerformanceEntryType, - durationThreshold?: HighResTimeStamp, + durationThreshold?: DOMHighResTimeStamp, }; type PerformanceObserverConfig = {| callback: PerformanceObserverCallback, - // Map of {entryType: durationThreshold} - entryTypes: $ReadOnlyMap, + entryTypes: $ReadOnlySet, + durationThreshold: ?number, |}; const observerCountPerEntryType: Map = new Map(); @@ -97,8 +100,15 @@ const onPerformanceEntry = () => { if (!observerConfig.entryTypes.has(entry.entryType)) { return false; } - const durationThreshold = observerConfig.entryTypes.get(entry.entryType); - return entry.duration >= (durationThreshold ?? 0); + + if ( + entry.entryType === 'event' && + observerConfig.durationThreshold != null + ) { + return entry.duration >= observerConfig.durationThreshold; + } + + return true; }); if (entriesForObserver.length !== 0) { try { @@ -122,21 +132,11 @@ export function warnNoNativePerformanceObserver() { } function applyDurationThresholds() { - const durationThresholds: Map = Array.from( - registeredObservers.values(), - ) - .map(config => config.entryTypes) - .reduce( - (accumulator, currentValue) => union(accumulator, currentValue), - new Map(), - ); - - for (const [entryType, durationThreshold] of durationThresholds) { - NativePerformanceObserver?.setDurationThreshold( - performanceEntryTypeToRaw(entryType), - durationThreshold ?? 0, - ); - } + const durationThresholds = Array.from(registeredObservers.values()) + .map(observerConfig => observerConfig.durationThreshold) + .filter(Boolean); + + return Math.min(...durationThresholds); } function getSupportedPerformanceEntryTypes(): $ReadOnlyArray { @@ -194,14 +194,10 @@ export default class PerformanceObserver { if (options.entryTypes) { this.#type = 'multiple'; - requestedEntryTypes = new Map( - options.entryTypes.map(t => [t, undefined]), - ); + requestedEntryTypes = new Set(options.entryTypes); } else { this.#type = 'single'; - requestedEntryTypes = new Map([ - [options.type, options.durationThreshold], - ]); + requestedEntryTypes = new Set([options.type]); } // The same observer may receive multiple calls to "observe", so we need @@ -218,6 +214,8 @@ export default class PerformanceObserver { registeredObservers.set(this, { callback: this.#callback, + durationThreshold: + options.type === 'event' ? options.durationThreshold : undefined, entryTypes: nextEntryTypes, }); @@ -322,20 +320,8 @@ export default class PerformanceObserver { getSupportedPerformanceEntryTypes(); } -// As a Set union, except if value exists in both, we take minimum -function union( - a: $ReadOnlyMap, - b: $ReadOnlyMap, -): Map { - const res = new Map(); - for (const [k, v] of a) { - if (!b.has(k)) { - res.set(k, v); - } else { - res.set(k, Math.min(v ?? 0, b.get(k) ?? 0)); - } - } - return res; +function union(a: $ReadOnlySet, b: $ReadOnlySet): Set { + return new Set([...a, ...b]); } function difference(a: $ReadOnlySet, b: $ReadOnlySet): Set { diff --git a/packages/react-native/src/private/webapis/performance/RawPerformanceEntry.js b/packages/react-native/src/private/webapis/performance/RawPerformanceEntry.js index 861a0fd6580a..3a4e540e275f 100644 --- a/packages/react-native/src/private/webapis/performance/RawPerformanceEntry.js +++ b/packages/react-native/src/private/webapis/performance/RawPerformanceEntry.js @@ -14,8 +14,10 @@ import type { RawPerformanceEntryType, } from './specs/NativePerformanceObserver'; +import {PerformanceEventTiming} from './EventTiming'; +import {PerformanceLongTaskTiming} from './LongTasks'; import {PerformanceEntry} from './PerformanceEntry'; -import PerformanceEventTiming from './PerformanceEventTiming'; +import {PerformanceMark, PerformanceMeasure} from './UserTiming'; export const RawPerformanceEntryTypeValues = { MARK: 1, @@ -36,6 +38,22 @@ export function rawToPerformanceEntry( processingEnd: entry.processingEnd, interactionId: entry.interactionId, }); + } else if (entry.entryType === RawPerformanceEntryTypeValues.LONGTASK) { + return new PerformanceLongTaskTiming({ + name: entry.name, + entryType: rawToPerformanceEntryType(entry.entryType), + startTime: entry.startTime, + duration: entry.duration, + }); + } else if (entry.entryType === RawPerformanceEntryTypeValues.MARK) { + return new PerformanceMark(entry.name, { + startTime: entry.startTime, + }); + } else if (entry.entryType === RawPerformanceEntryTypeValues.MEASURE) { + return new PerformanceMeasure(entry.name, { + startTime: entry.startTime, + duration: entry.duration, + }); } else { return new PerformanceEntry({ name: entry.name, diff --git a/packages/react-native/src/private/webapis/performance/UserTiming.js b/packages/react-native/src/private/webapis/performance/UserTiming.js index 2380e71731e8..f3d7865a5cdc 100644 --- a/packages/react-native/src/private/webapis/performance/UserTiming.js +++ b/packages/react-native/src/private/webapis/performance/UserTiming.js @@ -8,24 +8,25 @@ * @flow strict */ -import type {HighResTimeStamp} from './PerformanceEntry'; +// flowlint unsafe-getters-setters:off + +import type {DOMHighResTimeStamp} from './PerformanceEntry'; import {PerformanceEntry} from './PerformanceEntry'; -type DetailType = mixed; +export type DetailType = mixed; export type PerformanceMarkOptions = { detail?: DetailType, - startTime?: HighResTimeStamp, + startTime?: DOMHighResTimeStamp, }; -export type TimeStampOrName = HighResTimeStamp | string; +export type TimeStampOrName = DOMHighResTimeStamp | string; -export type PerformanceMeasureOptions = { +export type PerformanceMeasureInit = { detail?: DetailType, - start?: TimeStampOrName, - end?: TimeStampOrName, - duration?: HighResTimeStamp, + startTime?: DOMHighResTimeStamp, + duration?: DOMHighResTimeStamp, }; export class PerformanceMark extends PerformanceEntry { @@ -46,18 +47,22 @@ export class PerformanceMark extends PerformanceEntry { } export class PerformanceMeasure extends PerformanceEntry { - detail: DetailType; + #detail: DetailType; - constructor(measureName: string, measureOptions?: PerformanceMeasureOptions) { + constructor(measureName: string, measureOptions?: PerformanceMeasureInit) { super({ name: measureName, entryType: 'measure', - startTime: 0, + startTime: measureOptions?.startTime ?? 0, duration: measureOptions?.duration ?? 0, }); if (measureOptions) { - this.detail = measureOptions.detail; + this.#detail = measureOptions.detail; } } + + get detail(): DetailType { + return this.#detail; + } } diff --git a/packages/react-native/src/private/webapis/performance/__tests__/PerformanceObserver-test.js b/packages/react-native/src/private/webapis/performance/__tests__/PerformanceObserver-test.js index 06cfbff59cd8..35cf1e1062c7 100644 --- a/packages/react-native/src/private/webapis/performance/__tests__/PerformanceObserver-test.js +++ b/packages/react-native/src/private/webapis/performance/__tests__/PerformanceObserver-test.js @@ -52,49 +52,74 @@ describe('PerformanceObserver', () => { const observer = new PerformanceObserver((list, _observer) => {}); expect(() => - observer.observe({entryTypes: ['mark'], durationThreshold: 100}), + observer.observe({entryTypes: ['event', 'mark'], durationThreshold: 100}), ).toThrow(); }); + it('ignores durationThreshold when used with marks or measures', async () => { + let entries = []; + + const observer = new PerformanceObserver((list, _observer) => { + entries = [...entries, ...list.getEntries()]; + }); + + observer.observe({type: 'measure', durationThreshold: 100}); + + NativePerformanceObserver.logRawEntry({ + name: 'measure1', + entryType: RawPerformanceEntryTypeValues.MEASURE, + startTime: 0, + duration: 200, + }); + + await jest.runAllTicks(); + expect(entries).toHaveLength(1); + expect(entries.map(e => e.name)).toStrictEqual(['measure1']); + }); + it('handles durationThreshold argument as expected', async () => { let entries = []; const observer = new PerformanceObserver((list, _observer) => { entries = [...entries, ...list.getEntries()]; }); - observer.observe({type: 'mark', durationThreshold: 100}); + observer.observe({type: 'event', durationThreshold: 100}); NativePerformanceObserver.logRawEntry({ - name: 'mark1', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event1', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 200, }); NativePerformanceObserver.logRawEntry({ - name: 'mark2', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event2', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 20, }); NativePerformanceObserver.logRawEntry({ - name: 'mark3', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event3', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 100, }); NativePerformanceObserver.logRawEntry({ - name: 'mark4', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event4', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 500, }); await jest.runAllTicks(); expect(entries).toHaveLength(3); - expect(entries.map(e => e.name)).toStrictEqual(['mark1', 'mark3', 'mark4']); + expect(entries.map(e => e.name)).toStrictEqual([ + 'event1', + 'event3', + 'event4', + ]); }); it('correctly works with multiple PerformanceObservers with durationThreshold', async () => { @@ -118,36 +143,36 @@ describe('PerformanceObserver', () => { entries4 = [...entries4, ...list.getEntries()]; }); - observer2.observe({type: 'mark', durationThreshold: 200}); - observer1.observe({type: 'mark', durationThreshold: 100}); - observer3.observe({type: 'mark', durationThreshold: 300}); - observer3.observe({type: 'measure', durationThreshold: 500}); - observer4.observe({entryTypes: ['mark', 'measure']}); + observer2.observe({type: 'event', durationThreshold: 200}); + observer1.observe({type: 'event', durationThreshold: 100}); + observer3.observe({type: 'event', durationThreshold: 300}); + observer3.observe({type: 'event', durationThreshold: 500}); + observer4.observe({entryTypes: ['event']}); NativePerformanceObserver.logRawEntry({ - name: 'mark1', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event1', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 200, }); NativePerformanceObserver.logRawEntry({ - name: 'mark2', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event2', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 20, }); NativePerformanceObserver.logRawEntry({ - name: 'mark3', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event3', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 100, }); NativePerformanceObserver.logRawEntry({ - name: 'mark4', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event4', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 500, }); @@ -156,15 +181,15 @@ describe('PerformanceObserver', () => { observer1.disconnect(); NativePerformanceObserver.logRawEntry({ - name: 'mark5', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event5', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 200, }); NativePerformanceObserver.logRawEntry({ - name: 'mark6', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event6', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 300, }); @@ -173,8 +198,8 @@ describe('PerformanceObserver', () => { observer3.disconnect(); NativePerformanceObserver.logRawEntry({ - name: 'mark7', - entryType: RawPerformanceEntryTypeValues.MARK, + name: 'event7', + entryType: RawPerformanceEntryTypeValues.EVENT, startTime: 0, duration: 200, }); @@ -183,26 +208,26 @@ describe('PerformanceObserver', () => { observer4.disconnect(); expect(entries1.map(e => e.name)).toStrictEqual([ - 'mark1', - 'mark3', - 'mark4', + 'event1', + 'event3', + 'event4', ]); expect(entries2.map(e => e.name)).toStrictEqual([ - 'mark1', - 'mark4', - 'mark5', - 'mark6', - 'mark7', + 'event1', + 'event4', + 'event5', + 'event6', + 'event7', ]); - expect(entries3.map(e => e.name)).toStrictEqual(['mark4', 'mark6']); + expect(entries3.map(e => e.name)).toStrictEqual(['event4', 'event6']); expect(entries4.map(e => e.name)).toStrictEqual([ - 'mark1', - 'mark2', - 'mark3', - 'mark4', - 'mark5', - 'mark6', - 'mark7', + 'event1', + 'event2', + 'event3', + 'event4', + 'event5', + 'event6', + 'event7', ]); });