diff --git a/packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js b/packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js
index f47200c6f0e21..81333c8e5abd0 100644
--- a/packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js
+++ b/packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js
@@ -7,10 +7,13 @@
'use strict';
+import {getLaneLabels} from 'react-reconciler/src/SchedulingProfiler';
import preprocessData, {
+ SUPPORTED_PROFILER_VERSION,
getLanesFromTransportDecimalBitmask,
} from '../preprocessData';
import {REACT_TOTAL_NUM_LANES} from '../../constants';
+import REACT_VERSION from 'shared/ReactVersion';
describe(getLanesFromTransportDecimalBitmask, () => {
it('should return array of lane numbers from bitmask string', () => {
@@ -109,6 +112,35 @@ describe(preprocessData, () => {
};
}
+ function createProfilerVersionEntry() {
+ return createUserTimingEntry({
+ cat: 'blink.user_timing',
+ name: '--profiler-version-' + SUPPORTED_PROFILER_VERSION,
+ });
+ }
+
+ function createReactVersionEntry() {
+ return createUserTimingEntry({
+ cat: 'blink.user_timing',
+ name: '--react-version-' + REACT_VERSION,
+ });
+ }
+
+ function createLaneLabelsEntry() {
+ return createUserTimingEntry({
+ cat: 'blink.user_timing',
+ name: '--react-lane-labels-' + getLaneLabels().join(','),
+ });
+ }
+
+ function createBoilerplateEntries() {
+ return [
+ createProfilerVersionEntry(),
+ createReactVersionEntry(),
+ createLaneLabelsEntry(),
+ ];
+ }
+
function createUserTimingData(sampleMarks) {
const cpuProfilerSample = createUserTimingEntry({
args: {data: {startTime: ++startTime}},
@@ -192,7 +224,6 @@ describe(preprocessData, () => {
name: 'Profile',
ph: 'P',
});
-
const randomSample = createUserTimingEntry({
dur: 100,
tdur: 200,
@@ -202,20 +233,62 @@ describe(preprocessData, () => {
args: {},
});
- expect(preprocessData([cpuProfilerSample, randomSample])).toStrictEqual({
- componentMeasures: [],
- duration: 0.002,
- flamechart: [],
- measures: [],
- nativeEvents: [],
- otherUserTimingMarks: [],
- schedulingEvents: [],
- startTime: 1,
- suspenseEvents: [],
- });
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ const data = preprocessData([
+ ...createBoilerplateEntries(),
+ cpuProfilerSample,
+ randomSample,
+ ]);
+ expect(data).toMatchInlineSnapshot(`
+ Object {
+ "componentMeasures": Array [],
+ "duration": 0.005,
+ "flamechart": Array [],
+ "laneToLabelMap": Map {
+ 0 => "Sync",
+ 1 => "InputContinuousHydration",
+ 2 => "InputContinuous",
+ 3 => "DefaultHydration",
+ 4 => "Default",
+ 5 => "TransitionHydration",
+ 6 => "Transition",
+ 7 => "Transition",
+ 8 => "Transition",
+ 9 => "Transition",
+ 10 => "Transition",
+ 11 => "Transition",
+ 12 => "Transition",
+ 13 => "Transition",
+ 14 => "Transition",
+ 15 => "Transition",
+ 16 => "Transition",
+ 17 => "Transition",
+ 18 => "Transition",
+ 19 => "Transition",
+ 20 => "Transition",
+ 21 => "Transition",
+ 22 => "Retry",
+ 23 => "Retry",
+ 24 => "Retry",
+ 25 => "Retry",
+ 26 => "Retry",
+ 27 => "SelectiveHydration",
+ 28 => "IdleHydration",
+ 29 => "Idle",
+ 30 => "Offscreen",
+ },
+ "measures": Array [],
+ "nativeEvents": Array [],
+ "otherUserTimingMarks": Array [],
+ "reactVersion": "17.0.3",
+ "schedulingEvents": Array [],
+ "startTime": 1,
+ "suspenseEvents": Array [],
+ }
+ `);
+ }
});
- // NOTE This test doesn't have to be gated because it has hard-coded profiler samples.
it('should process legacy data format (before lane labels were added)', () => {
const cpuProfilerSample = createUserTimingEntry({
args: {data: {startTime: ++startTime}},
@@ -225,10 +298,11 @@ describe(preprocessData, () => {
ph: 'P',
});
- expect(
+ if (gate(flags => flags.enableSchedulingProfiler)) {
// Data below is hard-coded based on an older profile sample.
// Should be fine since this is explicitly a legacy-format test.
- preprocessData([
+ const data = preprocessData([
+ ...createBoilerplateEntries(),
cpuProfilerSample,
createUserTimingEntry({
cat: 'blink.user_timing',
@@ -258,140 +332,220 @@ describe(preprocessData, () => {
cat: 'blink.user_timing',
name: '--commit-stop',
}),
- ]),
- ).toStrictEqual({
- componentMeasures: [],
- duration: 0.008,
- flamechart: [],
- measures: [
- {
- batchUID: 0,
- depth: 0,
- duration: 0.005,
- laneLabels: [],
- lanes: [9],
- timestamp: 0.003,
- type: 'render-idle',
- },
- {
- batchUID: 0,
- depth: 0,
- duration: 0.001,
- laneLabels: [],
- lanes: [9],
- timestamp: 0.003,
- type: 'render',
- },
- {
- batchUID: 0,
- depth: 0,
- duration: 0.003,
- laneLabels: [],
- lanes: [9],
- timestamp: 0.005,
- type: 'commit',
+ ]);
+ expect(data).toMatchInlineSnapshot(`
+ Object {
+ "componentMeasures": Array [],
+ "duration": 0.011,
+ "flamechart": Array [],
+ "laneToLabelMap": Map {
+ 0 => "Sync",
+ 1 => "InputContinuousHydration",
+ 2 => "InputContinuous",
+ 3 => "DefaultHydration",
+ 4 => "Default",
+ 5 => "TransitionHydration",
+ 6 => "Transition",
+ 7 => "Transition",
+ 8 => "Transition",
+ 9 => "Transition",
+ 10 => "Transition",
+ 11 => "Transition",
+ 12 => "Transition",
+ 13 => "Transition",
+ 14 => "Transition",
+ 15 => "Transition",
+ 16 => "Transition",
+ 17 => "Transition",
+ 18 => "Transition",
+ 19 => "Transition",
+ 20 => "Transition",
+ 21 => "Transition",
+ 22 => "Retry",
+ 23 => "Retry",
+ 24 => "Retry",
+ 25 => "Retry",
+ 26 => "Retry",
+ 27 => "SelectiveHydration",
+ 28 => "IdleHydration",
+ 29 => "Idle",
+ 30 => "Offscreen",
},
- {
- batchUID: 0,
- depth: 1,
- duration: 0.001,
- laneLabels: [],
- lanes: [9],
- timestamp: 0.006,
- type: 'layout-effects',
- },
- ],
- nativeEvents: [],
- otherUserTimingMarks: [],
- schedulingEvents: [
- {
- laneLabels: [],
- lanes: [9],
- timestamp: 0.002,
- type: 'schedule-render',
- warning: null,
- },
- ],
- startTime: 1,
- suspenseEvents: [],
- });
+ "measures": Array [
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.004999999999999999,
+ "lanes": Array [
+ 9,
+ ],
+ "timestamp": 0.006,
+ "type": "render-idle",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.001,
+ "lanes": Array [
+ 9,
+ ],
+ "timestamp": 0.006,
+ "type": "render",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.002999999999999999,
+ "lanes": Array [
+ 9,
+ ],
+ "timestamp": 0.008,
+ "type": "commit",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 1,
+ "duration": 0.0010000000000000009,
+ "lanes": Array [
+ 9,
+ ],
+ "timestamp": 0.009,
+ "type": "layout-effects",
+ },
+ ],
+ "nativeEvents": Array [],
+ "otherUserTimingMarks": Array [],
+ "reactVersion": "17.0.3",
+ "schedulingEvents": Array [
+ Object {
+ "lanes": Array [
+ 9,
+ ],
+ "timestamp": 0.005,
+ "type": "schedule-render",
+ "warning": null,
+ },
+ ],
+ "startTime": 1,
+ "suspenseEvents": Array [],
+ }
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should process a sample legacy render sequence', () => {
ReactDOM.render(
, document.createElement('div'));
- const reactVersion = require('shared/ReactVersion').default;
-
- const userTimingData = createUserTimingData(clearedMarks);
- expect(preprocessData(userTimingData)).toStrictEqual({
- componentMeasures: [],
- duration: 0.011,
- flamechart: [],
- measures: [
- {
- batchUID: 0,
- depth: 0,
- duration: 0.004999999999999999,
- laneLabels: ['Sync'],
- lanes: [0],
- timestamp: 0.006,
- type: 'render-idle',
- },
- {
- batchUID: 0,
- depth: 0,
- duration: 0.001,
- laneLabels: ['Sync'],
- lanes: [0],
- timestamp: 0.006,
- type: 'render',
- },
- {
- batchUID: 0,
- depth: 0,
- duration: 0.002999999999999999,
- laneLabels: ['Sync'],
- lanes: [0],
- timestamp: 0.008,
- type: 'commit',
- },
- {
- batchUID: 0,
- depth: 1,
- duration: 0.0010000000000000009,
- laneLabels: ['Sync'],
- lanes: [0],
- timestamp: 0.009,
- type: 'layout-effects',
- },
- ],
- nativeEvents: [],
- otherUserTimingMarks: [
- {
- name: '__v3',
- timestamp: 0.003,
- },
- {
- name: `--react-init-${reactVersion}`,
- timestamp: 0.004,
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ const data = preprocessData([
+ ...createBoilerplateEntries(),
+ ...createUserTimingData(clearedMarks),
+ ]);
+ expect(data).toMatchInlineSnapshot(`
+ Object {
+ "componentMeasures": Array [],
+ "duration": 0.013,
+ "flamechart": Array [],
+ "laneToLabelMap": Map {
+ 0 => "Sync",
+ 1 => "InputContinuousHydration",
+ 2 => "InputContinuous",
+ 3 => "DefaultHydration",
+ 4 => "Default",
+ 5 => "TransitionHydration",
+ 6 => "Transition",
+ 7 => "Transition",
+ 8 => "Transition",
+ 9 => "Transition",
+ 10 => "Transition",
+ 11 => "Transition",
+ 12 => "Transition",
+ 13 => "Transition",
+ 14 => "Transition",
+ 15 => "Transition",
+ 16 => "Transition",
+ 17 => "Transition",
+ 18 => "Transition",
+ 19 => "Transition",
+ 20 => "Transition",
+ 21 => "Transition",
+ 22 => "Retry",
+ 23 => "Retry",
+ 24 => "Retry",
+ 25 => "Retry",
+ 26 => "Retry",
+ 27 => "SelectiveHydration",
+ 28 => "IdleHydration",
+ 29 => "Idle",
+ 30 => "Offscreen",
},
- ],
- schedulingEvents: [
- {
- laneLabels: ['Sync'],
- lanes: [0],
- timestamp: 0.005,
- type: 'schedule-render',
- warning: null,
- },
- ],
- startTime: 1,
- suspenseEvents: [],
- });
+ "measures": Array [
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.008,
+ "lanes": Array [
+ 0,
+ ],
+ "timestamp": 0.005,
+ "type": "render-idle",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.001,
+ "lanes": Array [
+ 0,
+ ],
+ "timestamp": 0.005,
+ "type": "render",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.005999999999999999,
+ "lanes": Array [
+ 0,
+ ],
+ "timestamp": 0.007,
+ "type": "commit",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 1,
+ "duration": 0.0010000000000000009,
+ "lanes": Array [
+ 0,
+ ],
+ "timestamp": 0.011,
+ "type": "layout-effects",
+ },
+ ],
+ "nativeEvents": Array [],
+ "otherUserTimingMarks": Array [
+ Object {
+ "name": "__v3",
+ "timestamp": 0.003,
+ },
+ ],
+ "reactVersion": "17.0.3",
+ "schedulingEvents": Array [
+ Object {
+ "lanes": Array [
+ 0,
+ ],
+ "timestamp": 0.004,
+ "type": "schedule-render",
+ "warning": null,
+ },
+ ],
+ "startTime": 4,
+ "suspenseEvents": Array [],
+ }
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should process a sample createRoot render sequence', () => {
function App() {
const [didMount, setDidMount] = React.useState(false);
@@ -403,150 +557,199 @@ describe(preprocessData, () => {
return true;
}
- const root = ReactDOM.createRoot(document.createElement('div'));
- act(() => root.render());
-
- const userTimingData = createUserTimingData(clearedMarks);
- expect(preprocessData(userTimingData)).toStrictEqual({
- componentMeasures: [
- {
- componentName: 'App',
- duration: 0.001,
- timestamp: 0.007,
- warning: null,
- },
- {
- componentName: 'App',
- duration: 0.0010000000000000009,
- timestamp: 0.018,
- warning: null,
- },
- ],
- duration: 0.026,
- flamechart: [],
- measures: [
- {
- batchUID: 0,
- depth: 0,
- duration: 0.006999999999999999,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.006,
- type: 'render-idle',
- },
- {
- batchUID: 0,
- depth: 0,
- duration: 0.002999999999999999,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.006,
- type: 'render',
- },
- {
- batchUID: 0,
- depth: 0,
- duration: 0.002999999999999999,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.01,
- type: 'commit',
- },
- {
- batchUID: 0,
- depth: 1,
- duration: 0.0010000000000000009,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.011,
- type: 'layout-effects',
- },
- {
- batchUID: 0,
- depth: 0,
- duration: 0.002,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.014,
- type: 'passive-effects',
- },
- {
- batchUID: 1,
- depth: 0,
- duration: 0.006999999999999999,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.017,
- type: 'render-idle',
- },
- {
- batchUID: 1,
- depth: 0,
- duration: 0.002999999999999999,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.017,
- type: 'render',
- },
- {
- batchUID: 1,
- depth: 0,
- duration: 0.002999999999999999,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.021,
- type: 'commit',
- },
- {
- batchUID: 1,
- depth: 1,
- duration: 0.0010000000000000009,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.022,
- type: 'layout-effects',
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ const root = ReactDOM.createRoot(document.createElement('div'));
+ act(() => root.render());
+
+ const data = preprocessData([
+ ...createBoilerplateEntries(),
+ ...createUserTimingData(clearedMarks),
+ ]);
+ expect(data).toMatchInlineSnapshot(`
+ Object {
+ "componentMeasures": Array [
+ Object {
+ "componentName": "App",
+ "duration": 0.001,
+ "timestamp": 0.006,
+ "warning": null,
+ },
+ Object {
+ "componentName": "App",
+ "duration": 0.0010000000000000009,
+ "timestamp": 0.02,
+ "warning": null,
+ },
+ ],
+ "duration": 0.031,
+ "flamechart": Array [],
+ "laneToLabelMap": Map {
+ 0 => "Sync",
+ 1 => "InputContinuousHydration",
+ 2 => "InputContinuous",
+ 3 => "DefaultHydration",
+ 4 => "Default",
+ 5 => "TransitionHydration",
+ 6 => "Transition",
+ 7 => "Transition",
+ 8 => "Transition",
+ 9 => "Transition",
+ 10 => "Transition",
+ 11 => "Transition",
+ 12 => "Transition",
+ 13 => "Transition",
+ 14 => "Transition",
+ 15 => "Transition",
+ 16 => "Transition",
+ 17 => "Transition",
+ 18 => "Transition",
+ 19 => "Transition",
+ 20 => "Transition",
+ 21 => "Transition",
+ 22 => "Retry",
+ 23 => "Retry",
+ 24 => "Retry",
+ 25 => "Retry",
+ 26 => "Retry",
+ 27 => "SelectiveHydration",
+ 28 => "IdleHydration",
+ 29 => "Idle",
+ 30 => "Offscreen",
},
- {
- batchUID: 1,
- depth: 0,
- duration: 0.0009999999999999974,
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.025,
- type: 'passive-effects',
- },
- ],
- nativeEvents: [],
- otherUserTimingMarks: [
- {
- name: '__v3',
- timestamp: 0.003,
- },
- {
- name: '--react-init-17.0.3',
- timestamp: 0.004,
- },
- ],
- schedulingEvents: [
- {
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.005,
- type: 'schedule-render',
- warning: null,
- },
- {
- componentName: 'App',
- laneLabels: ['Default'],
- lanes: [4],
- timestamp: 0.015,
- type: 'schedule-state-update',
- warning: null,
- },
- ],
- startTime: 1,
- suspenseEvents: [],
- });
+ "measures": Array [
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.009999999999999998,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.005,
+ "type": "render-idle",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.003,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.005,
+ "type": "render",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.006,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.009,
+ "type": "commit",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 1,
+ "duration": 0.0010000000000000009,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.013,
+ "type": "layout-effects",
+ },
+ Object {
+ "batchUID": 0,
+ "depth": 0,
+ "duration": 0.0019999999999999983,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.016,
+ "type": "passive-effects",
+ },
+ Object {
+ "batchUID": 1,
+ "depth": 0,
+ "duration": 0.010000000000000002,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.019,
+ "type": "render-idle",
+ },
+ Object {
+ "batchUID": 1,
+ "depth": 0,
+ "duration": 0.002999999999999999,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.019,
+ "type": "render",
+ },
+ Object {
+ "batchUID": 1,
+ "depth": 0,
+ "duration": 0.006000000000000002,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.023,
+ "type": "commit",
+ },
+ Object {
+ "batchUID": 1,
+ "depth": 1,
+ "duration": 0.0010000000000000009,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.027,
+ "type": "layout-effects",
+ },
+ Object {
+ "batchUID": 1,
+ "depth": 0,
+ "duration": 0.0010000000000000009,
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.03,
+ "type": "passive-effects",
+ },
+ ],
+ "nativeEvents": Array [],
+ "otherUserTimingMarks": Array [
+ Object {
+ "name": "__v3",
+ "timestamp": 0.003,
+ },
+ ],
+ "reactVersion": "17.0.3",
+ "schedulingEvents": Array [
+ Object {
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.004,
+ "type": "schedule-render",
+ "warning": null,
+ },
+ Object {
+ "componentName": "App",
+ "lanes": Array [
+ 4,
+ ],
+ "timestamp": 0.017,
+ "type": "schedule-state-update",
+ "warning": null,
+ },
+ ],
+ "startTime": 4,
+ "suspenseEvents": Array [],
+ }
+ `);
+ }
});
// @gate enableSchedulingProfiler
@@ -560,7 +763,7 @@ describe(preprocessData, () => {
const invalidUserTimingData = createUserTimingData(invalidMarks);
const error = spyOnDevAndProd(console, 'error');
- preprocessData(invalidUserTimingData);
+ preprocessData([...createBoilerplateEntries(), ...invalidUserTimingData]);
expect(error).toHaveBeenCalled();
});
@@ -575,7 +778,7 @@ describe(preprocessData, () => {
const invalidUserTimingData = createUserTimingData(invalidMarks);
const error = spyOnDevAndProd(console, 'error');
- preprocessData(invalidUserTimingData);
+ preprocessData([...createBoilerplateEntries(), ...invalidUserTimingData]);
expect(error).toHaveBeenCalled();
});
@@ -606,20 +809,26 @@ describe(preprocessData, () => {
}),
);
- expect(preprocessData(userTimingData).otherUserTimingMarks).toStrictEqual([
- {
- name: 'VCWithoutImage: root',
- timestamp: 0.003,
- },
- {
- name: '--a-mark-that-looks-like-one-of-ours',
- timestamp: 0.004,
- },
- {
- name: 'Some other mark',
- timestamp: 0.005,
- },
+ const data = preprocessData([
+ ...createBoilerplateEntries(),
+ ...userTimingData,
]);
+ expect(data.otherUserTimingMarks).toMatchInlineSnapshot(`
+ Array [
+ Object {
+ "name": "VCWithoutImage: root",
+ "timestamp": 0.003,
+ },
+ Object {
+ "name": "--a-mark-that-looks-like-one-of-ours",
+ "timestamp": 0.004,
+ },
+ Object {
+ "name": "Some other mark",
+ "timestamp": 0.005,
+ },
+ ]
+ `);
});
// TODO: Add test for flamechart parsing
diff --git a/packages/react-devtools-scheduling-profiler/src/import-worker/preprocessData.js b/packages/react-devtools-scheduling-profiler/src/import-worker/preprocessData.js
index 75f10b4c9570d..60c0c36c11a32 100644
--- a/packages/react-devtools-scheduling-profiler/src/import-worker/preprocessData.js
+++ b/packages/react-devtools-scheduling-profiler/src/import-worker/preprocessData.js
@@ -47,7 +47,7 @@ type ProcessorState = {|
// Increment this number any time a backwards breaking change is made to the profiler metadata.
// It should be in sync with the version in react-reconciler/src/SchedulingProfiler
-const SUPPORTED_PROFILER_VERSION = 1;
+export const SUPPORTED_PROFILER_VERSION = 1;
const NATIVE_EVENT_DURATION_THRESHOLD = 20;
diff --git a/packages/react-reconciler/src/SchedulingProfiler.js b/packages/react-reconciler/src/SchedulingProfiler.js
index 504202b1c9c07..461d30666a555 100644
--- a/packages/react-reconciler/src/SchedulingProfiler.js
+++ b/packages/react-reconciler/src/SchedulingProfiler.js
@@ -71,9 +71,9 @@ if (enableSchedulingProfiler) {
}
}
-const laneLabels: Array = [];
+const laneLabels: Array = [];
-function markLaneToLabelMetadata() {
+export function getLaneLabels(): Array {
if (laneLabels.length === 0) {
let lane = 1;
for (let index = 0; index < TotalLanes; index++) {
@@ -82,6 +82,11 @@ function markLaneToLabelMetadata() {
lane *= 2;
}
}
+ return laneLabels;
+}
+
+function markLaneToLabelMetadata() {
+ getLaneLabels();
markAndClear(`--react-lane-labels-${laneLabels.join(',')}`);
}
diff --git a/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js b/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js
index 4b496b732a21d..8680d19b710bf 100644
--- a/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js
@@ -10,17 +10,6 @@
'use strict';
-// This test is *.internal so that it can import this shared file.
-import ReactVersion from 'shared/ReactVersion';
-
-// Hard-coding because importing will not work with bundle tests and to
-// avoid leaking exports for lanes that are only imported in this test.
-const ReactFiberLane = {
- SyncLane: /* */ 0b0000000000000000000000000000001,
- DefaultLane: /* */ 0b0000000000000000000000000010000,
- TransitionLane1: /* */ 0b0000000000000000000000001000000,
-};
-
describe('SchedulingProfiler', () => {
let React;
let ReactTestRenderer;
@@ -30,7 +19,6 @@ describe('SchedulingProfiler', () => {
let clearedMarks;
let featureDetectionMarkName = null;
- let formatLanes;
let marks;
function createUserTimingPolyfill() {
@@ -63,16 +51,10 @@ describe('SchedulingProfiler', () => {
clearedMarks.splice(0);
}
- function expectMarksToContain(expectedMarks) {
- expect(clearedMarks).toContain(expectedMarks);
- }
-
- function expectMarksToEqual(expectedMarks) {
- expect(
- clearedMarks[0] === featureDetectionMarkName
- ? clearedMarks.slice(1)
- : clearedMarks,
- ).toEqual(expectedMarks);
+ function getMarks() {
+ return clearedMarks[0] === featureDetectionMarkName
+ ? clearedMarks.slice(1)
+ : clearedMarks;
}
beforeEach(() => {
@@ -88,9 +70,6 @@ describe('SchedulingProfiler', () => {
Scheduler = require('scheduler');
act = require('jest-react').act;
-
- const SchedulingProfiler = require('react-reconciler/src/SchedulingProfiler');
- formatLanes = SchedulingProfiler.formatLanes;
});
afterEach(() => {
@@ -103,54 +82,62 @@ describe('SchedulingProfiler', () => {
// @gate !enableSchedulingProfiler
it('should not mark if enableSchedulingProfiler is false', () => {
ReactTestRenderer.create();
- expectMarksToEqual([]);
+ expect(getMarks()).toEqual([]);
});
- // @gate enableSchedulingProfiler
- it('should log React version on initialization', () => {
- expectMarksToEqual([`--react-init-${ReactVersion}`]);
- });
-
- // @gate enableSchedulingProfiler
it('should mark sync render without suspends or state updates', () => {
ReactTestRenderer.create();
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`,
- `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--layout-effects-stop',
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-1",
+ "--render-start-1",
+ "--render-stop",
+ "--commit-start-1",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-1",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark concurrent render without suspends or state updates', () => {
ReactTestRenderer.create(, {unstable_isConcurrent: true});
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ ]
+ `);
+ }
clearPendingMarks();
expect(Scheduler).toFlushUntilNextPaint([]);
- expectMarksToEqual([
- `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--layout-effects-stop',
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--render-start-16",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark render yields', async () => {
function Bar() {
Scheduler.unstable_yieldValue('Bar');
@@ -170,30 +157,31 @@ describe('SchedulingProfiler', () => {
// Do one step of work.
expect(ReactNoop.flushNextYield()).toEqual(['Foo']);
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.TransitionLane1)}`,
- `--render-start-${formatLanes(ReactFiberLane.TransitionLane1)}`,
- '--component-render-start-Foo',
- '--component-render-stop',
- '--render-yield',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-64",
+ "--render-start-64",
+ "--component-render-start-Foo",
+ "--component-render-stop",
+ "--render-yield",
+ ]
+ `);
+ }
} else {
ReactNoop.render();
// Do one step of work.
expect(ReactNoop.flushNextYield()).toEqual(['Foo']);
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--render-yield',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array []
+ `);
+ }
}
});
- // @gate enableSchedulingProfiler
it('should mark sync render with suspense that resolves', async () => {
const fakeSuspensePromise = Promise.resolve(true);
function Example() {
@@ -206,27 +194,38 @@ describe('SchedulingProfiler', () => {
,
);
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`,
- `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--suspense-suspend-0-Example-mount-1-Sync',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--layout-effects-stop',
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-1",
+ "--render-start-1",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--suspense-suspend-0-Example-mount-1",
+ "--render-stop",
+ "--commit-start-1",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-1",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
clearPendingMarks();
await fakeSuspensePromise;
- expectMarksToEqual(['--suspense-resolved-0-Example']);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--suspense-resolved-0-Example",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark sync render with suspense that rejects', async () => {
const fakeSuspensePromise = Promise.reject(new Error('error'));
function Example() {
@@ -239,27 +238,38 @@ describe('SchedulingProfiler', () => {
,
);
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`,
- `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--suspense-suspend-0-Example-mount-1-Sync',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--layout-effects-stop',
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-1",
+ "--render-start-1",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--suspense-suspend-0-Example-mount-1",
+ "--render-stop",
+ "--commit-start-1",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-1",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
clearPendingMarks();
await expect(fakeSuspensePromise).rejects.toThrow();
- expectMarksToEqual(['--suspense-rejected-0-Example']);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--suspense-rejected-0-Example",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark concurrent render with suspense that resolves', async () => {
const fakeSuspensePromise = Promise.resolve(true);
function Example() {
@@ -273,34 +283,49 @@ describe('SchedulingProfiler', () => {
{unstable_isConcurrent: true},
);
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ ]
+ `);
+ }
clearPendingMarks();
expect(Scheduler).toFlushUntilNextPaint([]);
- expectMarksToEqual([
- `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--suspense-suspend-0-Example-mount-16-Default',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--layout-effects-stop',
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--suspense-suspend-0-Example-mount-16",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
clearPendingMarks();
await fakeSuspensePromise;
- expectMarksToEqual(['--suspense-resolved-0-Example']);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--suspense-resolved-0-Example",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark concurrent render with suspense that rejects', async () => {
const fakeSuspensePromise = Promise.reject(new Error('error'));
function Example() {
@@ -314,34 +339,49 @@ describe('SchedulingProfiler', () => {
{unstable_isConcurrent: true},
);
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ ]
+ `);
+ }
clearPendingMarks();
expect(Scheduler).toFlushUntilNextPaint([]);
- expectMarksToEqual([
- `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--suspense-suspend-0-Example-mount-16-Default',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--layout-effects-stop',
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--suspense-suspend-0-Example-mount-16",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
clearPendingMarks();
await expect(fakeSuspensePromise).rejects.toThrow();
- expectMarksToEqual(['--suspense-rejected-0-Example']);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--suspense-rejected-0-Example",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark cascading class component state updates', () => {
class Example extends React.Component {
state = {didMount: false};
@@ -355,35 +395,47 @@ describe('SchedulingProfiler', () => {
ReactTestRenderer.create(, {unstable_isConcurrent: true});
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ ]
+ `);
+ }
clearPendingMarks();
expect(Scheduler).toFlushUntilNextPaint([]);
- expectMarksToEqual([
- `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--schedule-state-update-${formatLanes(ReactFiberLane.SyncLane)}-Example`,
- '--layout-effects-stop',
- `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--commit-stop',
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--schedule-state-update-1-Example",
+ "--layout-effects-stop",
+ "--render-start-1",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-1",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--commit-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark cascading class component force updates', () => {
class Example extends React.Component {
componentDidMount() {
@@ -396,37 +448,47 @@ describe('SchedulingProfiler', () => {
ReactTestRenderer.create(, {unstable_isConcurrent: true});
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ ]
+ `);
+ }
clearPendingMarks();
expect(Scheduler).toFlushUntilNextPaint([]);
- expectMarksToEqual([
- `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--schedule-forced-update-${formatLanes(
- ReactFiberLane.SyncLane,
- )}-Example`,
- '--layout-effects-stop',
- `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--commit-stop',
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--schedule-forced-update-1-Example",
+ "--layout-effects-stop",
+ "--render-start-1",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-1",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--commit-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark render phase state updates for class component', () => {
class Example extends React.Component {
state = {didRender: false};
@@ -440,10 +502,13 @@ describe('SchedulingProfiler', () => {
ReactTestRenderer.create(, {unstable_isConcurrent: true});
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ ]
+ `);
+ }
clearPendingMarks();
@@ -451,14 +516,26 @@ describe('SchedulingProfiler', () => {
expect(Scheduler).toFlushUntilNextPaint([]);
}).toErrorDev('Cannot update during an existing state transition');
- expectMarksToContain(
- `--schedule-state-update-${formatLanes(
- ReactFiberLane.DefaultLane,
- )}-Example`,
- );
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--schedule-state-update-16-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark render phase force updates for class component', () => {
class Example extends React.Component {
state = {didRender: false};
@@ -472,10 +549,13 @@ describe('SchedulingProfiler', () => {
ReactTestRenderer.create(, {unstable_isConcurrent: true});
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ ]
+ `);
+ }
clearPendingMarks();
@@ -483,14 +563,26 @@ describe('SchedulingProfiler', () => {
expect(Scheduler).toFlushUntilNextPaint([]);
}).toErrorDev('Cannot update during an existing state transition');
- expectMarksToContain(
- `--schedule-forced-update-${formatLanes(
- ReactFiberLane.DefaultLane,
- )}-Example`,
- );
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--schedule-forced-update-16-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark cascading layout updates', () => {
function Example() {
const [didMount, setDidMount] = React.useState(false);
@@ -502,37 +594,49 @@ describe('SchedulingProfiler', () => {
ReactTestRenderer.create(, {unstable_isConcurrent: true});
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ ]
+ `);
+ }
clearPendingMarks();
expect(Scheduler).toFlushUntilNextPaint([]);
- expectMarksToEqual([
- `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--schedule-state-update-${formatLanes(ReactFiberLane.SyncLane)}-Example`,
- '--layout-effects-stop',
- `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`,
- '--commit-stop',
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--schedule-state-update-1-Example",
+ "--layout-effects-stop",
+ "--render-start-1",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-1",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--commit-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
// This test is coupled to lane implementation details, so I'm disabling it in
// the new fork until it stabilizes so we don't have to repeatedly update it.
- // @gate enableSchedulingProfiler
it('should mark cascading passive updates', () => {
function Example() {
const [didMount, setDidMount] = React.useState(false);
@@ -546,32 +650,38 @@ describe('SchedulingProfiler', () => {
ReactTestRenderer.create(, {unstable_isConcurrent: true});
});
- expectMarksToEqual([
- `--react-init-${ReactVersion}`,
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--layout-effects-stop',
- '--commit-stop',
- `--passive-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- `--schedule-state-update-${formatLanes(
- ReactFiberLane.DefaultLane,
- )}-Example`,
- '--passive-effects-stop',
- `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--component-render-start-Example',
- '--component-render-stop',
- '--render-stop',
- `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`,
- '--commit-stop',
- ]);
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--layout-effects-stop",
+ "--commit-stop",
+ "--passive-effects-start-16",
+ "--schedule-state-update-16-Example",
+ "--passive-effects-stop",
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--commit-stop",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('should mark render phase updates', () => {
function Example() {
const [didRender, setDidRender] = React.useState(false);
@@ -585,10 +695,24 @@ describe('SchedulingProfiler', () => {
ReactTestRenderer.create(, {unstable_isConcurrent: true});
});
- expectMarksToContain(
- `--schedule-state-update-${formatLanes(
- ReactFiberLane.DefaultLane,
- )}-Example`,
- );
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(getMarks()).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-render-16",
+ "--render-start-16",
+ "--component-render-start-Example",
+ "--schedule-state-update-16-Example",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-16",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-16",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
});
diff --git a/packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js b/packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js
index 226607eaed2e2..09fdb95b01e6c 100644
--- a/packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js
@@ -15,12 +15,10 @@
describe('SchedulingProfiler labels', () => {
let React;
let ReactDOM;
- let ReactFiberLane;
let act;
let clearedMarks;
let featureDetectionMarkName = null;
- let formatLanes;
let marks;
function polyfillJSDomUserTiming() {
@@ -75,14 +73,6 @@ describe('SchedulingProfiler labels', () => {
const TestUtils = require('react-dom/test-utils');
act = TestUtils.act;
-
- const SchedulingProfiler = require('react-reconciler/src/SchedulingProfiler');
- formatLanes = SchedulingProfiler.formatLanes;
-
- const ReactFeatureFlags = require('shared/ReactFeatureFlags');
- ReactFiberLane = ReactFeatureFlags.enableNewReconciler
- ? require('react-reconciler/src/ReactFiberLane.new')
- : require('react-reconciler/src/ReactFiberLane.old');
});
afterEach(() => {
@@ -92,29 +82,45 @@ describe('SchedulingProfiler labels', () => {
delete global.performance;
});
- // @gate enableSchedulingProfiler
it('regression test SyncLane', () => {
ReactDOM.render(, document.createElement('div'));
- expect(clearedMarks).toContain(
- `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`,
- );
+
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ expect(clearedMarks).toMatchInlineSnapshot(`
+ Array [
+ "__v3",
+ "--schedule-render-1",
+ "--render-start-1",
+ "--render-stop",
+ "--commit-start-1",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-1",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('regression test DefaultLane', () => {
- const container = document.createElement('div');
- const root = ReactDOM.createRoot(container);
-
- act(() => {
- root.render();
- expect(clearedMarks).toContain(
- `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`,
- );
- });
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ act(() => {
+ const container = document.createElement('div');
+ const root = ReactDOM.createRoot(container);
+
+ root.render();
+ expect(clearedMarks).toMatchInlineSnapshot(`
+ Array [
+ "__v3",
+ "--schedule-render-16",
+ ]
+ `);
+ });
+ }
});
- // @gate enableSchedulingProfiler
- // @gate !enableLegacyFBSupport
it('regression test InputDiscreteLane', () => {
const container = document.createElement('div');
const root = ReactDOM.createRoot(container);
@@ -128,24 +134,41 @@ describe('SchedulingProfiler labels', () => {
return ;
}
- act(() => {
- root.render();
- });
-
- clearedMarks.splice(0);
-
- act(() => {
- targetRef.current.click();
- });
- expect(clearedMarks).toContain(
- `--schedule-state-update-${formatLanes(ReactFiberLane.SyncLane)}-App`,
- );
+ if (
+ gate(
+ flags => flags.enableSchedulingProfiler && !flags.enableLegacyFBSupport,
+ )
+ ) {
+ act(() => {
+ root.render();
+ });
+
+ clearedMarks.splice(0);
+
+ act(() => {
+ targetRef.current.click();
+ });
+
+ expect(clearedMarks).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-state-update-1-App",
+ "--render-start-1",
+ "--component-render-start-App",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-1",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-1",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
- // @gate enableSchedulingProfiler
it('regression test InputContinuousLane', () => {
- const container = document.createElement('div');
- const root = ReactDOM.createRoot(container);
const targetRef = React.createRef(null);
function App() {
@@ -154,21 +177,38 @@ describe('SchedulingProfiler labels', () => {
return ;
}
- act(() => {
- root.render();
- });
-
- clearedMarks.splice(0);
-
- act(() => {
- const event = document.createEvent('MouseEvents');
- event.initEvent('mouseover', true, true);
- dispatchAndSetCurrentEvent(targetRef.current, event);
- });
- expect(clearedMarks).toContain(
- `--schedule-state-update-${formatLanes(
- ReactFiberLane.InputContinuousLane,
- )}-App`,
- );
+ if (gate(flags => flags.enableSchedulingProfiler)) {
+ const container = document.createElement('div');
+ const root = ReactDOM.createRoot(container);
+
+ act(() => {
+ root.render();
+ });
+
+ clearedMarks.splice(0);
+
+ act(() => {
+ const event = document.createEvent('MouseEvents');
+ event.initEvent('mouseover', true, true);
+ dispatchAndSetCurrentEvent(targetRef.current, event);
+ });
+
+ expect(clearedMarks).toMatchInlineSnapshot(`
+ Array [
+ "--schedule-state-update-4-App",
+ "--render-start-4",
+ "--component-render-start-App",
+ "--component-render-stop",
+ "--render-stop",
+ "--commit-start-4",
+ "--react-version-17.0.3",
+ "--profiler-version-1",
+ "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen",
+ "--layout-effects-start-4",
+ "--layout-effects-stop",
+ "--commit-stop",
+ ]
+ `);
+ }
});
});