Files
react-native/Libraries/WebPerformance/__mocks__/NativePerformanceObserver.js
T
Ruslan Shestopalyuk 14ab76ac30 Hoist responsibility for clearMarks/Measures to NativePerformanceObserver (#36312)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36312

## Changelog:

[Internal] -

`clearMarks` and `clearMeasures` methods are incidental to the `NativePerformance` TurboModule functionality, as in reality this responsibility belongs more on the `NativePerformanceObserver` and `PerformanceEntryReporter` side.

This is something that [the standard indirectly suggests](https://www.w3.org/TR/user-timing/#clearmarks-method) as well (referencing [performance entry buffer](https://www.w3.org/TR/performance-timeline/#dfn-performance-entry-buffer)).

The new implementation should be also a little bit more efficient, as it avoids calling the predicate for each entry.

Finally (and frankly, the main reason for this change, from my perspective), it will simplify mocking/testing the JS part of the PerfAPI code.

Reviewed By: rubennorte

Differential Revision: D43621174

fbshipit-source-id: c4217a0da1d8ecbce797240627f7b4f057d85b97
2023-02-28 04:10:32 -08:00

91 lines
2.5 KiB
JavaScript

/**
* 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.
*
* @flow strict
* @format
*/
import type {
GetPendingEntriesResult,
RawPerformanceEntry,
RawPerformanceEntryType,
Spec as NativePerformanceObserver,
} from '../NativePerformanceObserver';
import {RawPerformanceEntryTypeValues} from '../RawPerformanceEntry';
const reportingType: Set<RawPerformanceEntryType> = new Set();
const eventCounts: Map<string, number> = new Map();
const durationThresholds: Map<RawPerformanceEntryType, number> = new Map();
let entries: Array<RawPerformanceEntry> = [];
let onPerformanceEntryCallback: ?() => void;
const NativePerformanceObserverMock: NativePerformanceObserver = {
startReporting: (entryType: RawPerformanceEntryType) => {
reportingType.add(entryType);
},
stopReporting: (entryType: RawPerformanceEntryType) => {
reportingType.delete(entryType);
durationThresholds.delete(entryType);
},
popPendingEntries: (): GetPendingEntriesResult => {
const res = entries;
entries = [];
return {
droppedEntriesCount: 0,
entries: res,
};
},
setOnPerformanceEntryCallback: (callback?: () => void) => {
onPerformanceEntryCallback = callback;
},
logRawEntry: (entry: RawPerformanceEntry) => {
if (reportingType.has(entry.entryType)) {
const durationThreshold = durationThresholds.get(entry.entryType);
if (
durationThreshold !== undefined &&
entry.duration < durationThreshold
) {
return;
}
entries.push(entry);
// $FlowFixMe[incompatible-call]
global.queueMicrotask(() => {
// We want to emulate the way it's done in native (i.e. async/batched)
onPerformanceEntryCallback?.();
});
}
if (entry.entryType === RawPerformanceEntryTypeValues.EVENT) {
eventCounts.set(entry.name, (eventCounts.get(entry.name) ?? 0) + 1);
}
},
getEventCounts: (): $ReadOnlyArray<[string, number]> => {
return Array.from(eventCounts.entries());
},
setDurationThreshold: (
entryType: RawPerformanceEntryType,
durationThreshold: number,
) => {
durationThresholds.set(entryType, durationThreshold);
},
clearEntries: (entryType: RawPerformanceEntryType, entryName?: string) => {
entries = entries.filter(
e =>
e.entryType === entryType &&
(entryName == null || e.name === entryName),
);
},
};
export default NativePerformanceObserverMock;