diff --git a/packages/react-reconciler/src/ReactFiberLane.new.js b/packages/react-reconciler/src/ReactFiberLane.new.js index e4280582e80cd..a1119043ea915 100644 --- a/packages/react-reconciler/src/ReactFiberLane.new.js +++ b/packages/react-reconciler/src/ReactFiberLane.new.js @@ -39,6 +39,7 @@ import invariant from 'shared/invariant'; import { enableCache, enableNonInterruptingNormalPri, + enableSchedulingProfiler, } from 'shared/ReactFeatureFlags'; import { @@ -127,6 +128,52 @@ const IdleLane: Lanes = /* */ 0b0100000000000000000 export const OffscreenLane: Lane = /* */ 0b1000000000000000000000000000000; +export function getLabelsForLanes(lanes: Lanes): Array | void { + if (enableSchedulingProfiler) { + const labels = []; + if (lanes & SyncLane) { + labels.push('Sync'); + } + if (lanes & SyncBatchedLane) { + labels.push('SyncBatched'); + } + if (lanes & InputDiscreteHydrationLane) { + labels.push('InputDiscreteHydration'); + } + if (lanes & InputDiscreteLane) { + labels.push('InputDiscrete'); + } + if (lanes & DefaultHydrationLane) { + labels.push('DefaultHydration'); + } + if (lanes & DefaultLane) { + labels.push('Default'); + } + if (lanes & TransitionHydrationLane) { + labels.push('TransitionHydration'); + } + if (lanes & TransitionLanes) { + labels.push('Transition(s)'); + } + if (lanes & RetryLanes) { + labels.push('Retry(s)'); + } + if (lanes & SelectiveHydrationLane) { + labels.push('SelectiveHydration'); + } + if (lanes & IdleHydrationLane) { + labels.push('IdleHydration'); + } + if (lanes & IdleLane) { + labels.push('Idle'); + } + if (lanes & OffscreenLane) { + labels.push('Offscreen'); + } + return labels; + } +} + export const NoTimestamp = -1; let currentUpdateLanePriority: LanePriority = NoLanePriority; diff --git a/packages/react-reconciler/src/ReactFiberLane.old.js b/packages/react-reconciler/src/ReactFiberLane.old.js index fe7d6eb7508c8..a661ede429a38 100644 --- a/packages/react-reconciler/src/ReactFiberLane.old.js +++ b/packages/react-reconciler/src/ReactFiberLane.old.js @@ -39,6 +39,7 @@ import invariant from 'shared/invariant'; import { enableCache, enableNonInterruptingNormalPri, + enableSchedulingProfiler, } from 'shared/ReactFeatureFlags'; import { @@ -127,6 +128,52 @@ const IdleLane: Lanes = /* */ 0b0100000000000000000 export const OffscreenLane: Lane = /* */ 0b1000000000000000000000000000000; +export function getLabelsForLanes(lanes: Lanes): Array | void { + if (enableSchedulingProfiler) { + const labels = []; + if (lanes & SyncLane) { + labels.push('Sync'); + } + if (lanes & SyncBatchedLane) { + labels.push('SyncBatched'); + } + if (lanes & InputDiscreteHydrationLane) { + labels.push('InputDiscreteHydration'); + } + if (lanes & InputDiscreteLane) { + labels.push('InputDiscrete'); + } + if (lanes & DefaultHydrationLane) { + labels.push('DefaultHydration'); + } + if (lanes & DefaultLane) { + labels.push('Default'); + } + if (lanes & TransitionHydrationLane) { + labels.push('TransitionHydration'); + } + if (lanes & TransitionLanes) { + labels.push('Transition(s)'); + } + if (lanes & RetryLanes) { + labels.push('Retry(s)'); + } + if (lanes & SelectiveHydrationLane) { + labels.push('SelectiveHydration'); + } + if (lanes & IdleHydrationLane) { + labels.push('IdleHydration'); + } + if (lanes & IdleLane) { + labels.push('Idle'); + } + if (lanes & OffscreenLane) { + labels.push('Offscreen'); + } + return labels; + } +} + export const NoTimestamp = -1; let currentUpdateLanePriority: LanePriority = NoLanePriority; diff --git a/packages/react-reconciler/src/SchedulingProfiler.js b/packages/react-reconciler/src/SchedulingProfiler.js index 0779b870a274b..ccc41f9854876 100644 --- a/packages/react-reconciler/src/SchedulingProfiler.js +++ b/packages/react-reconciler/src/SchedulingProfiler.js @@ -11,10 +11,20 @@ import type {Lane, Lanes} from './ReactFiberLane.old'; import type {Fiber} from './ReactInternalTypes'; import type {Wakeable} from 'shared/ReactTypes'; -import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags'; +import { + enableNewReconciler, + enableSchedulingProfiler, +} from 'shared/ReactFeatureFlags'; import ReactVersion from 'shared/ReactVersion'; import getComponentName from 'shared/getComponentName'; +import {getLabelsForLanes as getLabelsForLanes_old} from 'react-reconciler/src/ReactFiberLane.old'; +import {getLabelsForLanes as getLabelsForLanes_new} from 'react-reconciler/src/ReactFiberLane.new'; + +const getLabelsForLanes = enableNewReconciler + ? getLabelsForLanes_new + : getLabelsForLanes_old; + /** * If performance exists and supports the subset of the User Timing API that we * require. @@ -49,8 +59,14 @@ if (enableSchedulingProfiler) { } } -function formatLanes(laneOrLanes: Lane | Lanes): string { - return ((laneOrLanes: any): number).toString(); +export function formatLanes(laneOrLanes: Lane | Lanes): string { + let labels = getLabelsForLanes(laneOrLanes); + if (labels != null) { + labels = labels.sort().join(','); + } else { + labels = ''; + } + return `${laneOrLanes}-${labels}`; } function markAndClear(name) { diff --git a/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js b/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.js similarity index 70% rename from packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js rename to packages/react-reconciler/src/__tests__/SchedulingProfiler-test.js index dd3528da50fe1..10415906ba698 100644 --- a/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js +++ b/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.js @@ -17,9 +17,11 @@ describe('SchedulingProfiler', () => { let ReactTestRenderer; let ReactNoop; let Scheduler; + let ReactFiberLane; let clearedMarks; let featureDetectionMarkName = null; + let formatLanes; let marks; function createUserTimingPolyfill() { @@ -76,6 +78,14 @@ describe('SchedulingProfiler', () => { ReactNoop = require('react-noop-renderer'); Scheduler = require('scheduler'); + + 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(() => { @@ -85,9 +95,6 @@ describe('SchedulingProfiler', () => { delete global.performance; }); - // This is coupled to implementation - const DEFAULT_LANE = 128; - // @gate !enableSchedulingProfiler it('should not mark if enableSchedulingProfiler is false', () => { ReactTestRenderer.create(
); @@ -105,11 +112,11 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - '--schedule-render-1', - '--render-start-1', + `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`, + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--render-stop', - '--commit-start-1', - '--layout-effects-start-1', + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--layout-effects-stop', '--commit-stop', ]); @@ -121,7 +128,7 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, ]); clearPendingMarks(); @@ -129,10 +136,10 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); expectMarksToEqual([ - `--render-start-${DEFAULT_LANE}`, + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--render-stop', - `--commit-start-${DEFAULT_LANE}`, - `--layout-effects-start-${DEFAULT_LANE}`, + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--layout-effects-stop', '--commit-stop', ]); @@ -156,8 +163,8 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, - `--render-start-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--render-yield', ]); }); @@ -177,12 +184,12 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - '--schedule-render-1', - '--render-start-1', + `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`, + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--suspense-suspend-0-Example', '--render-stop', - '--commit-start-1', - '--layout-effects-start-1', + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--layout-effects-stop', '--commit-stop', ]); @@ -208,12 +215,12 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - '--schedule-render-1', - '--render-start-1', + `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`, + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--suspense-suspend-0-Example', '--render-stop', - '--commit-start-1', - '--layout-effects-start-1', + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--layout-effects-stop', '--commit-stop', ]); @@ -240,7 +247,7 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, ]); clearPendingMarks(); @@ -248,11 +255,11 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); expectMarksToEqual([ - `--render-start-${DEFAULT_LANE}`, + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--suspense-suspend-0-Example', '--render-stop', - `--commit-start-${DEFAULT_LANE}`, - `--layout-effects-start-${DEFAULT_LANE}`, + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--layout-effects-stop', '--commit-stop', ]); @@ -279,7 +286,7 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, ]); clearPendingMarks(); @@ -287,11 +294,11 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); expectMarksToEqual([ - `--render-start-${DEFAULT_LANE}`, + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--suspense-suspend-0-Example', '--render-stop', - `--commit-start-${DEFAULT_LANE}`, - `--layout-effects-start-${DEFAULT_LANE}`, + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--layout-effects-stop', '--commit-stop', ]); @@ -318,7 +325,7 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, ]); clearPendingMarks(); @@ -326,15 +333,15 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); expectMarksToEqual([ - `--render-start-${DEFAULT_LANE}`, + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--render-stop', - `--commit-start-${DEFAULT_LANE}`, - `--layout-effects-start-${DEFAULT_LANE}`, - '--schedule-state-update-1-Example', + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--schedule-state-update-${formatLanes(ReactFiberLane.SyncLane)}-Example`, '--layout-effects-stop', - '--render-start-1', + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--render-stop', - '--commit-start-1', + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--commit-stop', '--commit-stop', ]); @@ -355,7 +362,7 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, ]); clearPendingMarks(); @@ -363,15 +370,17 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); expectMarksToEqual([ - `--render-start-${DEFAULT_LANE}`, + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--render-stop', - `--commit-start-${DEFAULT_LANE}`, - `--layout-effects-start-${DEFAULT_LANE}`, - '--schedule-forced-update-1-Example', + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--schedule-forced-update-${formatLanes( + ReactFiberLane.SyncLane, + )}-Example`, '--layout-effects-stop', - '--render-start-1', + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--render-stop', - '--commit-start-1', + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--commit-stop', '--commit-stop', ]); @@ -393,7 +402,7 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, ]); clearPendingMarks(); @@ -402,7 +411,11 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); }).toErrorDev('Cannot update during an existing state transition'); - expectMarksToContain(`--schedule-state-update-${DEFAULT_LANE}-Example`); + expectMarksToContain( + `--schedule-state-update-${formatLanes( + ReactFiberLane.DefaultLane, + )}-Example`, + ); }); // @gate enableSchedulingProfiler @@ -421,7 +434,7 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, ]); clearPendingMarks(); @@ -430,7 +443,11 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); }).toErrorDev('Cannot update during an existing state transition'); - expectMarksToContain(`--schedule-forced-update-${DEFAULT_LANE}-Example`); + expectMarksToContain( + `--schedule-forced-update-${formatLanes( + ReactFiberLane.DefaultLane, + )}-Example`, + ); }); // @gate enableSchedulingProfiler @@ -447,7 +464,7 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, ]); clearPendingMarks(); @@ -455,15 +472,15 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); expectMarksToEqual([ - `--render-start-${DEFAULT_LANE}`, + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--render-stop', - `--commit-start-${DEFAULT_LANE}`, - `--layout-effects-start-${DEFAULT_LANE}`, - '--schedule-state-update-1-Example', + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--schedule-state-update-${formatLanes(ReactFiberLane.SyncLane)}-Example`, '--layout-effects-stop', - '--render-start-1', + `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--render-stop', - '--commit-start-1', + `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, '--commit-stop', '--commit-stop', ]); @@ -487,19 +504,21 @@ describe('SchedulingProfiler', () => { expectMarksToEqual([ `--react-init-${ReactVersion}`, - `--schedule-render-${DEFAULT_LANE}`, - `--render-start-${DEFAULT_LANE}`, + `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--render-stop', - `--commit-start-${DEFAULT_LANE}`, - `--layout-effects-start-${DEFAULT_LANE}`, + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--layout-effects-stop', '--commit-stop', - `--passive-effects-start-${DEFAULT_LANE}`, - `--schedule-state-update-${DEFAULT_LANE}-Example`, + `--passive-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, + `--schedule-state-update-${formatLanes( + ReactFiberLane.DefaultLane, + )}-Example`, '--passive-effects-stop', - `--render-start-${DEFAULT_LANE}`, + `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--render-stop', - `--commit-start-${DEFAULT_LANE}`, + `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, '--commit-stop', ]); }); @@ -518,6 +537,10 @@ describe('SchedulingProfiler', () => { ReactTestRenderer.create(, {unstable_isConcurrent: true}); }); - expectMarksToContain(`--schedule-state-update-${DEFAULT_LANE}-Example`); + expectMarksToContain( + `--schedule-state-update-${formatLanes( + ReactFiberLane.DefaultLane, + )}-Example`, + ); }); });