From afd954efbb2a797b1dc0ade138a6b62e926cea8c Mon Sep 17 00:00:00 2001 From: Ruslan Shestopalyuk Date: Thu, 29 Dec 2022 14:30:53 -0800 Subject: [PATCH] Add PerformanceEventTiming API, according to the standard Summary: Changelog: [Internal] This adds definition of `PerformanceEventTiming` interface, according to the W3C standard, so that [event timing](https://www.w3.org/TR/event-timing) data can be reported from native (the C++ part is in the next diff). See here: https://www.w3.org/TR/event-timing/#performanceeventtiming Reviewed By: christophpurrer Differential Revision: D42279486 fbshipit-source-id: 0dfbcd6e5a08fc1b89651bd35b24fb4e731f8b05 --- Libraries/WebPerformance/Performance.js | 4 +- Libraries/WebPerformance/PerformanceEntry.js | 45 +++++++++++++ .../WebPerformance/PerformanceEventTiming.js | 39 +++++++++++ .../WebPerformance/PerformanceObserver.js | 67 +++++++------------ 4 files changed, 111 insertions(+), 44 deletions(-) create mode 100644 Libraries/WebPerformance/PerformanceEntry.js create mode 100644 Libraries/WebPerformance/PerformanceEventTiming.js diff --git a/Libraries/WebPerformance/Performance.js b/Libraries/WebPerformance/Performance.js index 0feb344469702a..0c8ffb700d8a80 100644 --- a/Libraries/WebPerformance/Performance.js +++ b/Libraries/WebPerformance/Performance.js @@ -8,11 +8,11 @@ * @flow strict */ -import type {HighResTimeStamp} from './PerformanceObserver'; +import type {HighResTimeStamp} from './PerformanceEntry'; import warnOnce from '../Utilities/warnOnce'; import NativePerformance from './NativePerformance'; -import {PerformanceEntry} from './PerformanceObserver'; +import {PerformanceEntry} from './PerformanceEntry'; type DetailType = mixed; diff --git a/Libraries/WebPerformance/PerformanceEntry.js b/Libraries/WebPerformance/PerformanceEntry.js new file mode 100644 index 00000000000000..e7b757e2d04456 --- /dev/null +++ b/Libraries/WebPerformance/PerformanceEntry.js @@ -0,0 +1,45 @@ +/** + * 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 + */ + +export type HighResTimeStamp = number; +export type PerformanceEntryType = 'mark' | 'measure' | 'event' | 'first-input'; + +export class PerformanceEntry { + name: string; + entryType: PerformanceEntryType; + startTime: HighResTimeStamp; + duration: HighResTimeStamp; + + constructor(init: { + name: string, + entryType: PerformanceEntryType, + startTime: HighResTimeStamp, + duration: HighResTimeStamp, + }) { + this.name = init.name; + this.entryType = init.entryType; + this.startTime = init.startTime; + this.duration = init.duration; + } + + toJSON(): { + name: string, + entryType: PerformanceEntryType, + startTime: HighResTimeStamp, + duration: HighResTimeStamp, + } { + return { + name: this.name, + entryType: this.entryType, + startTime: this.startTime, + duration: this.duration, + }; + } +} diff --git a/Libraries/WebPerformance/PerformanceEventTiming.js b/Libraries/WebPerformance/PerformanceEventTiming.js new file mode 100644 index 00000000000000..43b971a12f2478 --- /dev/null +++ b/Libraries/WebPerformance/PerformanceEventTiming.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 + */ + +import type {HighResTimeStamp} from './PerformanceEntry'; + +import {PerformanceEntry} from './PerformanceEntry'; + +export class PerformanceEventTiming extends PerformanceEntry { + processingStart: HighResTimeStamp; + processingEnd: HighResTimeStamp; + interactionId: number; + + constructor(init: { + name: string, + startTime?: HighResTimeStamp, + duration?: HighResTimeStamp, + processingStart?: HighResTimeStamp, + processingEnd?: HighResTimeStamp, + interactionId?: number, + isFirstInput?: boolean, + }) { + super({ + name: init.name, + entryType: init.isFirstInput === true ? 'first-input' : 'measure', + startTime: init.startTime ?? 0, + duration: init.duration ?? 0, + }); + this.processingStart = init.processingStart ?? 0; + this.processingEnd = init.processingEnd ?? 0; + this.interactionId = init.interactionId ?? 0; + } +} diff --git a/Libraries/WebPerformance/PerformanceObserver.js b/Libraries/WebPerformance/PerformanceObserver.js index ed95f2db795994..e6bbc4a7e657ca 100644 --- a/Libraries/WebPerformance/PerformanceObserver.js +++ b/Libraries/WebPerformance/PerformanceObserver.js @@ -12,47 +12,14 @@ import type { RawPerformanceEntry, RawPerformanceEntryType, } from './NativePerformanceObserver'; +import type {PerformanceEntryType} from './PerformanceEntry'; import warnOnce from '../Utilities/warnOnce'; import NativePerformanceObserver, { RawPerformanceEntryTypeValues, } from './NativePerformanceObserver'; - -export type HighResTimeStamp = number; -export type PerformanceEntryType = 'mark' | 'measure' | 'event' | 'first-input'; - -export class PerformanceEntry { - name: string; - entryType: PerformanceEntryType; - startTime: HighResTimeStamp; - duration: HighResTimeStamp; - - constructor(init: { - name: string, - entryType: PerformanceEntryType, - startTime: HighResTimeStamp, - duration: HighResTimeStamp, - }) { - this.name = init.name; - this.entryType = init.entryType; - this.startTime = init.startTime; - this.duration = init.duration; - } - - toJSON(): { - name: string, - entryType: PerformanceEntryType, - startTime: HighResTimeStamp, - duration: HighResTimeStamp, - } { - return { - name: this.name, - entryType: this.entryType, - startTime: this.startTime, - duration: this.duration, - }; - } -} +import {PerformanceEntry} from './PerformanceEntry'; +import {PerformanceEventTiming} from './PerformanceEventTiming'; function rawToPerformanceEntryType( type: RawPerformanceEntryType, @@ -74,12 +41,28 @@ function rawToPerformanceEntryType( } function rawToPerformanceEntry(entry: RawPerformanceEntry): PerformanceEntry { - return new PerformanceEntry({ - name: entry.name, - entryType: rawToPerformanceEntryType(entry.entryType), - startTime: entry.startTime, - duration: entry.duration, - }); + if ( + entry.entryType === RawPerformanceEntryTypeValues.EVENT || + entry.entryType === RawPerformanceEntryTypeValues.FIRST_INPUT + ) { + return new PerformanceEventTiming({ + name: entry.name, + startTime: entry.startTime, + duration: entry.duration, + processingStart: entry.processingStart, + processingEnd: entry.processingEnd, + interactionId: entry.interactionId, + isFirstInput: + entry.entryType === RawPerformanceEntryTypeValues.FIRST_INPUT, + }); + } else { + return new PerformanceEntry({ + name: entry.name, + entryType: rawToPerformanceEntryType(entry.entryType), + startTime: entry.startTime, + duration: entry.duration, + }); + } } export type PerformanceEntryList = $ReadOnlyArray;