Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions packages/react-native/Libraries/Core/setUpPerformanceObserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -41,13 +103,13 @@ function getCachedEventCounts(): Map<string, number> {
});
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;
}
Expand Down
39 changes: 39 additions & 0 deletions packages/react-native/src/private/webapis/performance/LongTasks.js
Original file line number Diff line number Diff line change
@@ -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<TaskAttributionTiming>,
...
};

export class TaskAttributionTiming extends PerformanceEntry {}

const EMPTY_ATTRIBUTION: $ReadOnlyArray<TaskAttributionTiming> =
Object.preventExtensions([]);

export class PerformanceLongTaskTiming extends PerformanceEntry {
get attribution(): $ReadOnlyArray<TaskAttributionTiming> {
return EMPTY_ATTRIBUTION;
}

toJSON(): PerformanceLongTaskTimingJSON {
return {
...super.toJSON(),
attribution: this.attribution,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
...
};

Expand All @@ -25,29 +27,45 @@ export const ALWAYS_LOGGED_ENTRY_TYPES: $ReadOnlyArray<PerformanceEntryType> = [
];

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,
};
}
}

This file was deleted.

Loading