mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Remove (bad) implementation of the User Timing API from Systrace
Summary: The `Systrace` module implements a polyfill for the User Timing API that's: 1. Incompatible with the Web standard. This polyfill expects `performance.mark` and `performance.measure` to be used exactly like `Systrace.beginEvent` and `Systrace.endEvent` respectively. If not used like those functions, they throw an error at runtime, which is really bad. 2. Never actually used. See below. This polyfill is only installed if we're actually profiling on startup: https://www.internalfb.com/code/fbsource/[4d888a933920]/xplat/js/react-native-github/Libraries/Core/setUpSystrace.js?lines=17-21 While the only code that we have that uses this API is actually not installed if we're profiling: https://www.internalfb.com/code/fbsource/[4d888a933920]/xplat/js/react-native-github/Libraries/Core/setUpDeveloperTools.js?lines=20-21 This should be safe to remove then. We have plans to add proper support for this API in the short term, so this also gets out of the way of doing that. Additionally, installing this polyfill was the only reason why we had `setupSystrace`, so we can get rid of that too :) Changelog: [Internal] Reviewed By: javache Differential Revision: D39210813 fbshipit-source-id: a90b6237c311d2157069b41975d10b33f1f464ef
This commit is contained in:
committed by
Facebook GitHub Bot
parent
9e3156f4c2
commit
5efb4f09fd
@@ -28,7 +28,6 @@ const start = Date.now();
|
||||
|
||||
require('./setUpGlobals');
|
||||
require('./setUpPerformance');
|
||||
require('./setUpSystrace');
|
||||
require('./setUpErrorHandling');
|
||||
require('./polyfillPromise');
|
||||
require('./setUpRegeneratorRuntime');
|
||||
|
||||
@@ -1,21 +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.
|
||||
*
|
||||
* @flow strict
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Set up Systrace profiling hooks if necessary.
|
||||
* You can use this module directly, or just require InitializeCore.
|
||||
*/
|
||||
if (global.__RCTProfileIsProfiling) {
|
||||
const Systrace = require('../Performance/Systrace');
|
||||
Systrace.installReactHook();
|
||||
Systrace.setEnabled(true);
|
||||
}
|
||||
@@ -10,124 +10,14 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const invariant = require('invariant');
|
||||
|
||||
const TRACE_TAG_REACT_APPS = 1 << 17; // eslint-disable-line no-bitwise
|
||||
|
||||
let _enabled = false;
|
||||
let _asyncCookie = 0;
|
||||
const _markStack = [];
|
||||
let _markStackIndex = -1;
|
||||
let _canInstallReactHook = false;
|
||||
|
||||
// Implements a subset of User Timing API necessary for React measurements.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API
|
||||
const REACT_MARKER = '\u269B';
|
||||
const userTimingPolyfill = __DEV__
|
||||
? {
|
||||
mark(markName: string) {
|
||||
if (_enabled) {
|
||||
_markStackIndex++;
|
||||
_markStack[_markStackIndex] = markName;
|
||||
let systraceLabel = markName;
|
||||
// Since perf measurements are a shared namespace in User Timing API,
|
||||
// we prefix all React results with a React emoji.
|
||||
if (markName[0] === REACT_MARKER) {
|
||||
// This is coming from React.
|
||||
// Removing component IDs keeps trace colors stable.
|
||||
const indexOfId = markName.lastIndexOf(' (#');
|
||||
const cutoffIndex = indexOfId !== -1 ? indexOfId : markName.length;
|
||||
// Also cut off the emoji because it breaks Systrace
|
||||
systraceLabel = markName.slice(2, cutoffIndex);
|
||||
}
|
||||
Systrace.beginEvent(systraceLabel);
|
||||
}
|
||||
},
|
||||
measure(measureName: string, startMark: ?string, endMark: ?string) {
|
||||
if (_enabled) {
|
||||
invariant(
|
||||
typeof measureName === 'string' &&
|
||||
typeof startMark === 'string' &&
|
||||
typeof endMark === 'undefined',
|
||||
'Only performance.measure(string, string) overload is supported.',
|
||||
);
|
||||
const topMark = _markStack[_markStackIndex];
|
||||
invariant(
|
||||
startMark === topMark,
|
||||
'There was a mismatching performance.measure() call. ' +
|
||||
'Expected "%s" but got "%s."',
|
||||
topMark,
|
||||
startMark,
|
||||
);
|
||||
_markStackIndex--;
|
||||
// We can't use more descriptive measureName because Systrace doesn't
|
||||
// let us edit labels post factum.
|
||||
Systrace.endEvent();
|
||||
}
|
||||
},
|
||||
clearMarks(markName: string) {
|
||||
if (_enabled) {
|
||||
if (_markStackIndex === -1) {
|
||||
return;
|
||||
}
|
||||
if (markName === _markStack[_markStackIndex]) {
|
||||
// React uses this for "cancelling" started measurements.
|
||||
// Systrace doesn't support deleting measurements, so we just stop them.
|
||||
if (userTimingPolyfill != null) {
|
||||
userTimingPolyfill.measure(markName, markName);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
clearMeasures() {
|
||||
// React calls this to avoid memory leaks in browsers, but we don't keep
|
||||
// measurements anyway.
|
||||
},
|
||||
}
|
||||
: null;
|
||||
|
||||
function installPerformanceHooks(
|
||||
polyfill: null | $TEMPORARY$object<{
|
||||
clearMarks(markName: string): void,
|
||||
clearMeasures(): void,
|
||||
mark(markName: string): void,
|
||||
measure(measureName: string, startMark: ?string, endMark: ?string): void,
|
||||
}>,
|
||||
) {
|
||||
if (polyfill) {
|
||||
if (global.performance === undefined) {
|
||||
global.performance = {};
|
||||
}
|
||||
|
||||
Object.keys(polyfill).forEach(methodName => {
|
||||
if (typeof global.performance[methodName] !== 'function') {
|
||||
global.performance[methodName] = polyfill[methodName];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const Systrace = {
|
||||
installReactHook() {
|
||||
if (_enabled) {
|
||||
if (__DEV__) {
|
||||
installPerformanceHooks(userTimingPolyfill);
|
||||
}
|
||||
}
|
||||
_canInstallReactHook = true;
|
||||
},
|
||||
|
||||
setEnabled(enabled: boolean) {
|
||||
if (_enabled !== enabled) {
|
||||
if (__DEV__) {
|
||||
if (_canInstallReactHook) {
|
||||
if (enabled) {
|
||||
installPerformanceHooks(userTimingPolyfill);
|
||||
}
|
||||
}
|
||||
}
|
||||
_enabled = enabled;
|
||||
}
|
||||
_enabled = enabled;
|
||||
},
|
||||
|
||||
isEnabled(): boolean {
|
||||
@@ -213,4 +103,8 @@ if (__DEV__) {
|
||||
global[(global.__METRO_GLOBAL_PREFIX__ || '') + '__SYSTRACE'] = Systrace;
|
||||
}
|
||||
|
||||
if (global.__RCTProfileIsProfiling) {
|
||||
Systrace.setEnabled(true);
|
||||
}
|
||||
|
||||
module.exports = Systrace;
|
||||
|
||||
Reference in New Issue
Block a user