Sync scheduling profiler marks and debug tracing to new reconciler fork (#19375, #19376, #19396)

* Make enableSchedulingProfiler flag static

* Copied debug tracing and scheduler profiling to .new fork and updated feature flags

* Move profiler component stacks behind a feature flag
This commit is contained in:
Brian Vaughn
2020-07-17 11:24:26 -04:00
committed by GitHub
parent aec934af7f
commit 51267c4ac9
17 changed files with 382 additions and 46 deletions
@@ -16,6 +16,8 @@ import {Update, Snapshot} from './ReactSideEffectTags';
import {
debugRenderPhaseSideEffectsForStrictMode,
disableLegacyContext,
enableDebugTracing,
enableSchedulingProfiler,
warnAboutDeprecatedLifecycles,
} from 'shared/ReactFeatureFlags';
import ReactStrictModeWarnings from './ReactStrictModeWarnings.new';
@@ -27,7 +29,7 @@ import invariant from 'shared/invariant';
import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
import {resolveDefaultProps} from './ReactFiberLazyComponent.new';
import {StrictMode} from './ReactTypeOfMode';
import {DebugTracingMode, StrictMode} from './ReactTypeOfMode';
import {
enqueueUpdate,
@@ -55,8 +57,13 @@ import {
scheduleUpdateOnFiber,
} from './ReactFiberWorkLoop.new';
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
import {logForceUpdateScheduled, logStateUpdateScheduled} from './DebugTracing';
import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev';
import {
markForceUpdateScheduled,
markStateUpdateScheduled,
} from './SchedulingProfiler';
const fakeInternalInstance = {};
const isArray = Array.isArray;
@@ -203,6 +210,19 @@ const classComponentUpdater = {
enqueueUpdate(fiber, update);
scheduleUpdateOnFiber(fiber, lane, eventTime);
if (__DEV__) {
if (enableDebugTracing) {
if (fiber.mode & DebugTracingMode) {
const name = getComponentName(fiber.type) || 'Unknown';
logStateUpdateScheduled(name, lane, payload);
}
}
}
if (enableSchedulingProfiler) {
markStateUpdateScheduled(fiber, lane);
}
},
enqueueReplaceState(inst, payload, callback) {
const fiber = getInstance(inst);
@@ -223,6 +243,19 @@ const classComponentUpdater = {
enqueueUpdate(fiber, update);
scheduleUpdateOnFiber(fiber, lane, eventTime);
if (__DEV__) {
if (enableDebugTracing) {
if (fiber.mode & DebugTracingMode) {
const name = getComponentName(fiber.type) || 'Unknown';
logStateUpdateScheduled(name, lane, payload);
}
}
}
if (enableSchedulingProfiler) {
markStateUpdateScheduled(fiber, lane);
}
},
enqueueForceUpdate(inst, callback) {
const fiber = getInstance(inst);
@@ -242,6 +275,19 @@ const classComponentUpdater = {
enqueueUpdate(fiber, update);
scheduleUpdateOnFiber(fiber, lane, eventTime);
if (__DEV__) {
if (enableDebugTracing) {
if (fiber.mode & DebugTracingMode) {
const name = getComponentName(fiber.type) || 'Unknown';
logForceUpdateScheduled(name, lane);
}
}
}
if (enableSchedulingProfiler) {
markForceUpdateScheduled(fiber, lane);
}
},
};
@@ -24,9 +24,13 @@ import type {FiberRoot} from './ReactInternalTypes';
import type {OpaqueIDType} from './ReactFiberHostConfig';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {enableNewReconciler} from 'shared/ReactFeatureFlags';
import {
enableDebugTracing,
enableSchedulingProfiler,
enableNewReconciler,
} from 'shared/ReactFeatureFlags';
import {NoMode, BlockingMode} from './ReactTypeOfMode';
import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';
import {
NoLane,
NoLanes,
@@ -88,6 +92,8 @@ import {
warnAboutMultipleRenderersDEV,
} from './ReactMutableSource.new';
import {getIsRendering} from './ReactCurrentFiber';
import {logStateUpdateScheduled} from './DebugTracing';
import {markStateUpdateScheduled} from './SchedulingProfiler';
const {ReactCurrentDispatcher, ReactCurrentBatchConfig} = ReactSharedInternals;
@@ -1751,6 +1757,19 @@ function dispatchAction<S, A>(
}
scheduleUpdateOnFiber(fiber, lane, eventTime);
}
if (__DEV__) {
if (enableDebugTracing) {
if (fiber.mode & DebugTracingMode) {
const name = getComponentName(fiber.type) || 'Unknown';
logStateUpdateScheduled(name, lane, action);
}
}
}
if (enableSchedulingProfiler) {
markStateUpdateScheduled(fiber, lane);
}
}
export const ContextOnlyDispatcher: Dispatcher = {
@@ -39,6 +39,7 @@ import {
} from './ReactWorkTags';
import getComponentName from 'shared/getComponentName';
import invariant from 'shared/invariant';
import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {getPublicInstance} from './ReactFiberHostConfig';
import {
@@ -95,6 +96,7 @@ import {
setRefreshHandler,
findHostInstancesForRefresh,
} from './ReactFiberHotReloading.new';
import {markRenderScheduled} from './SchedulingProfiler';
export {registerMutableSourceForHydration} from './ReactMutableSource.new';
export {createPortal} from './ReactPortal';
@@ -273,6 +275,10 @@ export function updateContainer(
const suspenseConfig = requestCurrentSuspenseConfig();
const lane = requestUpdateLane(current, suspenseConfig);
if (enableSchedulingProfiler) {
markRenderScheduled(lane);
}
const context = getContextForSubtree(parentComponent);
if (container.context === null) {
container.context = context;
@@ -31,7 +31,11 @@ import {
ForceUpdateForLegacySuspense,
} from './ReactSideEffectTags';
import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent.new';
import {NoMode, BlockingMode} from './ReactTypeOfMode';
import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';
import {
enableDebugTracing,
enableSchedulingProfiler,
} from 'shared/ReactFeatureFlags';
import {createCapturedValue} from './ReactCapturedValue';
import {
enqueueCapturedUpdate,
@@ -54,6 +58,8 @@ import {
pingSuspendedRoot,
} from './ReactFiberWorkLoop.new';
import {logCapturedError} from './ReactFiberErrorLogger';
import {logComponentSuspended} from './DebugTracing';
import {markComponentSuspended} from './SchedulingProfiler';
import {
SyncLane,
@@ -190,6 +196,19 @@ function throwException(
// This is a wakeable.
const wakeable: Wakeable = (value: any);
if (__DEV__) {
if (enableDebugTracing) {
if (sourceFiber.mode & DebugTracingMode) {
const name = getComponentName(sourceFiber.type) || 'Unknown';
logComponentSuspended(name, wakeable);
}
}
}
if (enableSchedulingProfiler) {
markComponentSuspended(sourceFiber, wakeable);
}
if ((sourceFiber.mode & BlockingMode) === NoMode) {
// Reset the memoizedState to what it was before we attempted
// to render it.
@@ -27,6 +27,8 @@ import {
warnAboutUnmockedScheduler,
deferRenderPhaseUpdateToNextBatch,
decoupleUpdatePriorityFromScheduler,
enableDebugTracing,
enableSchedulingProfiler,
enableScopeAPI,
} from 'shared/ReactFeatureFlags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
@@ -47,6 +49,27 @@ import {
flushSyncCallbackQueue,
scheduleSyncCallback,
} from './SchedulerWithReactIntegration.new';
import {
logCommitStarted,
logCommitStopped,
logLayoutEffectsStarted,
logLayoutEffectsStopped,
logPassiveEffectsStarted,
logPassiveEffectsStopped,
logRenderStarted,
logRenderStopped,
} from './DebugTracing';
import {
markCommitStarted,
markCommitStopped,
markLayoutEffectsStarted,
markLayoutEffectsStopped,
markPassiveEffectsStarted,
markPassiveEffectsStopped,
markRenderStarted,
markRenderYielded,
markRenderStopped,
} from './SchedulingProfiler';
// The scheduler is imported here *only* to detect whether it's been mocked
import * as Scheduler from 'scheduler';
@@ -1516,6 +1539,16 @@ function renderRootSync(root: FiberRoot, lanes: Lanes) {
const prevInteractions = pushInteractions(root);
if (__DEV__) {
if (enableDebugTracing) {
logRenderStarted(lanes);
}
}
if (enableSchedulingProfiler) {
markRenderStarted(lanes);
}
do {
try {
workLoopSync();
@@ -1541,6 +1574,16 @@ function renderRootSync(root: FiberRoot, lanes: Lanes) {
);
}
if (__DEV__) {
if (enableDebugTracing) {
logRenderStopped();
}
}
if (enableSchedulingProfiler) {
markRenderStopped();
}
// Set this to null to indicate there's no in-progress render.
workInProgressRoot = null;
workInProgressRootRenderLanes = NoLanes;
@@ -1571,6 +1614,16 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
const prevInteractions = pushInteractions(root);
if (__DEV__) {
if (enableDebugTracing) {
logRenderStarted(lanes);
}
}
if (enableSchedulingProfiler) {
markRenderStarted(lanes);
}
do {
try {
workLoopConcurrent();
@@ -1587,12 +1640,25 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
popDispatcher(prevDispatcher);
executionContext = prevExecutionContext;
if (__DEV__) {
if (enableDebugTracing) {
logRenderStopped();
}
}
// Check if the tree has completed.
if (workInProgress !== null) {
// Still work remaining.
if (enableSchedulingProfiler) {
markRenderYielded();
}
return RootIncomplete;
} else {
// Completed the tree.
if (enableSchedulingProfiler) {
markRenderStopped();
}
// Set this to null to indicate there's no in-progress render.
workInProgressRoot = null;
workInProgressRootRenderLanes = NoLanes;
@@ -1950,7 +2016,28 @@ function commitRootImpl(root, renderPriorityLevel) {
const finishedWork = root.finishedWork;
const lanes = root.finishedLanes;
if (__DEV__) {
if (enableDebugTracing) {
logCommitStarted(lanes);
}
}
if (enableSchedulingProfiler) {
markCommitStarted(lanes);
}
if (finishedWork === null) {
if (__DEV__) {
if (enableDebugTracing) {
logCommitStopped();
}
}
if (enableSchedulingProfiler) {
markCommitStopped();
}
return null;
}
root.finishedWork = null;
@@ -2062,8 +2149,27 @@ function commitRootImpl(root, renderPriorityLevel) {
// The next phase is the layout phase, where we call effects that read
// the host tree after it's been mutated. The idiomatic use case for this is
// layout, but class component lifecycles also fire here for legacy reasons.
if (__DEV__) {
if (enableDebugTracing) {
logLayoutEffectsStarted(lanes);
}
}
if (enableSchedulingProfiler) {
markLayoutEffectsStarted(lanes);
}
commitLayoutEffects(finishedWork, root, lanes);
if (__DEV__) {
if (enableDebugTracing) {
logLayoutEffectsStopped();
}
}
if (enableSchedulingProfiler) {
markLayoutEffectsStopped();
}
// Tell Scheduler to yield at the end of the frame, so the browser has an
// opportunity to paint.
requestPaint();
@@ -2165,6 +2271,16 @@ function commitRootImpl(root, renderPriorityLevel) {
}
if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
if (__DEV__) {
if (enableDebugTracing) {
logCommitStopped();
}
}
if (enableSchedulingProfiler) {
markCommitStopped();
}
// This is a legacy edge case. We just committed the initial mount of
// a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
// synchronously, but layout updates should be deferred until the end
@@ -2175,6 +2291,16 @@ function commitRootImpl(root, renderPriorityLevel) {
// If layout work was scheduled, flush it now.
flushSyncCallbackQueue();
if (__DEV__) {
if (enableDebugTracing) {
logCommitStopped();
}
}
if (enableSchedulingProfiler) {
markCommitStopped();
}
return null;
}
@@ -2572,6 +2698,16 @@ function flushPassiveEffectsImpl() {
'Cannot flush passive effects while already rendering.',
);
if (__DEV__) {
if (enableDebugTracing) {
logPassiveEffectsStarted(lanes);
}
}
if (enableSchedulingProfiler) {
markPassiveEffectsStarted(lanes);
}
if (__DEV__) {
isFlushingPassiveEffects = true;
}
@@ -2716,6 +2852,16 @@ function flushPassiveEffectsImpl() {
isFlushingPassiveEffects = false;
}
if (__DEV__) {
if (enableDebugTracing) {
logPassiveEffectsStopped();
}
}
if (enableSchedulingProfiler) {
markPassiveEffectsStopped();
}
executionContext = prevExecutionContext;
flushSyncCallbackQueue();
@@ -1361,7 +1361,7 @@ function handleError(root, thrownValue): void {
// sibling, or the parent if there are no siblings. But since the root
// has no siblings nor a parent, we set it to null. Usually this is
// handled by `completeUnitOfWork` or `unwindWork`, but since we're
// interntionally not calling those, we need set it here.
// intentionally not calling those, we need set it here.
// TODO: Consider calling `unwindWork` to pop the contexts.
workInProgress = null;
return;
+31 -18
View File
@@ -11,7 +11,10 @@ import type {Lane, Lanes} from './ReactFiberLane';
import type {Fiber} from './ReactInternalTypes';
import type {Wakeable} from 'shared/ReactTypes';
import {enableSchedulingProfiler} from 'shared/ReactFeatureFlags';
import {
enableSchedulingProfiler,
enableSchedulingProfilerComponentStacks,
} from 'shared/ReactFeatureFlags';
import getComponentName from 'shared/getComponentName';
import {getStackByFiberInDevAndProd} from './ReactFiberComponentStack';
@@ -54,21 +57,31 @@ function getWakeableID(wakeable: Wakeable): number {
return ((wakeableIDs.get(wakeable): any): number);
}
// $FlowFixMe: Flow cannot handle polymorphic WeakMaps
const cachedFiberStacks: WeakMap<Fiber, string> = new PossiblyWeakMap();
function cacheFirstGetComponentStackByFiber(fiber: Fiber): string {
if (cachedFiberStacks.has(fiber)) {
return ((cachedFiberStacks.get(fiber): any): string);
} else {
const alternate = fiber.alternate;
if (alternate !== null && cachedFiberStacks.has(alternate)) {
return ((cachedFiberStacks.get(alternate): any): string);
let getComponentStackByFiber = function getComponentStackByFiberDisabled(
fiber: Fiber,
): string {
return '';
};
if (enableSchedulingProfilerComponentStacks) {
// $FlowFixMe: Flow cannot handle polymorphic WeakMaps
const cachedFiberStacks: WeakMap<Fiber, string> = new PossiblyWeakMap();
getComponentStackByFiber = function cacheFirstGetComponentStackByFiber(
fiber: Fiber,
): string {
if (cachedFiberStacks.has(fiber)) {
return ((cachedFiberStacks.get(fiber): any): string);
} else {
const alternate = fiber.alternate;
if (alternate !== null && cachedFiberStacks.has(alternate)) {
return ((cachedFiberStacks.get(alternate): any): string);
}
}
}
// TODO (brian) Generate and store temporary ID so DevTools can match up a component stack later.
const componentStack = getStackByFiberInDevAndProd(fiber) || '';
cachedFiberStacks.set(fiber, componentStack);
return componentStack;
// TODO (brian) Generate and store temporary ID so DevTools can match up a component stack later.
const componentStack = getStackByFiberInDevAndProd(fiber) || '';
cachedFiberStacks.set(fiber, componentStack);
return componentStack;
};
}
export function markComponentSuspended(fiber: Fiber, wakeable: Wakeable): void {
@@ -76,7 +89,7 @@ export function markComponentSuspended(fiber: Fiber, wakeable: Wakeable): void {
if (supportsUserTiming) {
const id = getWakeableID(wakeable);
const componentName = getComponentName(fiber.type) || 'Unknown';
const componentStack = cacheFirstGetComponentStackByFiber(fiber);
const componentStack = getComponentStackByFiber(fiber);
performance.mark(
`--suspense-suspend-${id}-${componentName}-${componentStack}`,
);
@@ -162,7 +175,7 @@ export function markForceUpdateScheduled(fiber: Fiber, lane: Lane): void {
if (enableSchedulingProfiler) {
if (supportsUserTiming) {
const componentName = getComponentName(fiber.type) || 'Unknown';
const componentStack = cacheFirstGetComponentStackByFiber(fiber);
const componentStack = getComponentStackByFiber(fiber);
performance.mark(
`--schedule-forced-update-${formatLanes(
lane,
@@ -176,7 +189,7 @@ export function markStateUpdateScheduled(fiber: Fiber, lane: Lane): void {
if (enableSchedulingProfiler) {
if (supportsUserTiming) {
const componentName = getComponentName(fiber.type) || 'Unknown';
const componentStack = cacheFirstGetComponentStackByFiber(fiber);
const componentStack = getComponentStackByFiber(fiber);
performance.mark(
`--schedule-state-update-${formatLanes(
lane,
@@ -19,6 +19,20 @@ function normalizeCodeLocInfo(str) {
);
}
// TODO (enableSchedulingProfilerComponentStacks) Clean this up once the feature flag has been removed.
function toggleComponentStacks(mark) {
let expectedMark = mark;
gate(({enableSchedulingProfilerComponentStacks}) => {
if (!enableSchedulingProfilerComponentStacks) {
const index = mark.indexOf('\n ');
if (index >= 0) {
expectedMark = mark.substr(0, index);
}
}
});
return expectedMark;
}
describe('SchedulingProfiler', () => {
let React;
let ReactTestRenderer;
@@ -136,7 +150,9 @@ describe('SchedulingProfiler', () => {
expect(marks).toEqual([
'--schedule-render-1',
'--render-start-1',
'--suspense-suspend-0-Example-\n at Example\n at Suspense',
toggleComponentStacks(
'--suspense-suspend-0-Example-\n at Example\n at Suspense',
),
'--render-stop',
'--commit-start-1',
'--layout-effects-start-1',
@@ -148,7 +164,9 @@ describe('SchedulingProfiler', () => {
await fakeSuspensePromise;
expect(marks).toEqual([
'--suspense-resolved-0-Example-\n at Example\n at Suspense',
toggleComponentStacks(
'--suspense-resolved-0-Example-\n at Example\n at Suspense',
),
]);
});
@@ -168,7 +186,9 @@ describe('SchedulingProfiler', () => {
expect(marks).toEqual([
'--schedule-render-1',
'--render-start-1',
'--suspense-suspend-0-Example-\n at Example\n at Suspense',
toggleComponentStacks(
'--suspense-suspend-0-Example-\n at Example\n at Suspense',
),
'--render-stop',
'--commit-start-1',
'--layout-effects-start-1',
@@ -180,7 +200,9 @@ describe('SchedulingProfiler', () => {
await expect(fakeSuspensePromise).rejects.toThrow();
expect(marks).toEqual([
'--suspense-rejected-0-Example-\n at Example\n at Suspense',
toggleComponentStacks(
'--suspense-rejected-0-Example-\n at Example\n at Suspense',
),
]);
});
@@ -206,7 +228,9 @@ describe('SchedulingProfiler', () => {
expect(marks).toEqual([
'--render-start-512',
'--suspense-suspend-0-Example-\n at Example\n at Suspense',
toggleComponentStacks(
'--suspense-suspend-0-Example-\n at Example\n at Suspense',
),
'--render-stop',
'--commit-start-512',
'--layout-effects-start-512',
@@ -218,7 +242,9 @@ describe('SchedulingProfiler', () => {
await fakeSuspensePromise;
expect(marks).toEqual([
'--suspense-resolved-0-Example-\n at Example\n at Suspense',
toggleComponentStacks(
'--suspense-resolved-0-Example-\n at Example\n at Suspense',
),
]);
});
@@ -244,7 +270,9 @@ describe('SchedulingProfiler', () => {
expect(marks).toEqual([
'--render-start-512',
'--suspense-suspend-0-Example-\n at Example\n at Suspense',
toggleComponentStacks(
'--suspense-suspend-0-Example-\n at Example\n at Suspense',
),
'--render-stop',
'--commit-start-512',
'--layout-effects-start-512',
@@ -256,7 +284,9 @@ describe('SchedulingProfiler', () => {
await expect(fakeSuspensePromise).rejects.toThrow();
expect(marks).toEqual([
'--suspense-rejected-0-Example-\n at Example\n at Suspense',
toggleComponentStacks(
'--suspense-rejected-0-Example-\n at Example\n at Suspense',
),
]);
});
@@ -285,7 +315,9 @@ describe('SchedulingProfiler', () => {
'--render-stop',
'--commit-start-512',
'--layout-effects-start-512',
'--schedule-state-update-1-Example-\n in Example (at **)',
toggleComponentStacks(
'--schedule-state-update-1-Example-\n in Example (at **)',
),
'--layout-effects-stop',
'--render-start-1',
'--render-stop',
@@ -319,7 +351,9 @@ describe('SchedulingProfiler', () => {
'--render-stop',
'--commit-start-512',
'--layout-effects-start-512',
'--schedule-forced-update-1-Example-\n in Example (at **)',
toggleComponentStacks(
'--schedule-forced-update-1-Example-\n in Example (at **)',
),
'--layout-effects-stop',
'--render-start-1',
'--render-stop',
@@ -351,8 +385,18 @@ describe('SchedulingProfiler', () => {
expect(Scheduler).toFlushUntilNextPaint([]);
}).toErrorDev('Cannot update during an existing state transition');
expect(marks.map(normalizeCodeLocInfo)).toContain(
'--schedule-state-update-1024-Example-\n in Example (at **)',
gate(({old}) =>
old
? expect(marks.map(normalizeCodeLocInfo)).toContain(
toggleComponentStacks(
'--schedule-state-update-1024-Example-\n in Example (at **)',
),
)
: expect(marks.map(normalizeCodeLocInfo)).toContain(
toggleComponentStacks(
'--schedule-state-update-512-Example-\n in Example (at **)',
),
),
);
});
@@ -378,8 +422,18 @@ describe('SchedulingProfiler', () => {
expect(Scheduler).toFlushUntilNextPaint([]);
}).toErrorDev('Cannot update during an existing state transition');
expect(marks.map(normalizeCodeLocInfo)).toContain(
'--schedule-forced-update-1024-Example-\n in Example (at **)',
gate(({old}) =>
old
? expect(marks.map(normalizeCodeLocInfo)).toContain(
toggleComponentStacks(
'--schedule-forced-update-1024-Example-\n in Example (at **)',
),
)
: expect(marks.map(normalizeCodeLocInfo)).toContain(
toggleComponentStacks(
'--schedule-forced-update-512-Example-\n in Example (at **)',
),
),
);
});
@@ -406,7 +460,9 @@ describe('SchedulingProfiler', () => {
'--render-stop',
'--commit-start-512',
'--layout-effects-start-512',
'--schedule-state-update-1-Example-\n in Example (at **)',
toggleComponentStacks(
'--schedule-state-update-1-Example-\n in Example (at **)',
),
'--layout-effects-stop',
'--render-start-1',
'--render-stop',
@@ -429,6 +485,7 @@ describe('SchedulingProfiler', () => {
ReactTestRenderer.act(() => {
ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
});
expect(marks.map(normalizeCodeLocInfo)).toEqual([
'--schedule-render-512',
'--render-start-512',
@@ -438,7 +495,9 @@ describe('SchedulingProfiler', () => {
'--layout-effects-stop',
'--commit-stop',
'--passive-effects-start-512',
'--schedule-state-update-1024-Example-\n in Example (at **)',
toggleComponentStacks(
'--schedule-state-update-1024-Example-\n in Example (at **)',
),
'--passive-effects-stop',
'--render-start-1024',
'--render-stop',
@@ -461,8 +520,18 @@ describe('SchedulingProfiler', () => {
ReactTestRenderer.create(<Example />, {unstable_isConcurrent: true});
});
expect(marks.map(normalizeCodeLocInfo)).toContain(
'--schedule-state-update-1024-Example-\n in Example (at **)',
gate(({old}) =>
old
? expect(marks.map(normalizeCodeLocInfo)).toContain(
toggleComponentStacks(
'--schedule-state-update-1024-Example-\n in Example (at **)',
),
)
: expect(marks.map(normalizeCodeLocInfo)).toContain(
toggleComponentStacks(
'--schedule-state-update-512-Example-\n in Example (at **)',
),
),
);
});
});
+2 -1
View File
@@ -17,7 +17,8 @@ export const enableDebugTracing = false;
// Adds user timing marks for e.g. state updates, suspense, and work loop stuff,
// for an experimental scheduling profiler tool.
export const enableSchedulingProfiler = false;
export const enableSchedulingProfiler = __PROFILE__ && __EXPERIMENTAL__;
export const enableSchedulingProfilerComponentStacks = false;
// Helps identify side effects in render-phase lifecycle hooks and setState
// reducers by double invoking them in Strict Mode.
@@ -13,6 +13,7 @@ import typeof * as ExportsType from './ReactFeatureFlags.native-fb';
// The rest of the flags are static for better dead code elimination.
export const enableDebugTracing = false;
export const enableSchedulingProfiler = false;
export const enableSchedulingProfilerComponentStacks = false;
export const enableProfilerTimer = __PROFILE__;
export const enableProfilerCommitHooks = false;
export const enableSchedulerTracing = __PROFILE__;
@@ -13,6 +13,7 @@ import typeof * as ExportsType from './ReactFeatureFlags.native-oss';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableDebugTracing = false;
export const enableSchedulingProfiler = false;
export const enableSchedulingProfilerComponentStacks = false;
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
export const warnAboutDeprecatedLifecycles = true;
export const enableProfilerTimer = __PROFILE__;
@@ -13,6 +13,7 @@ import typeof * as ExportsType from './ReactFeatureFlags.test-renderer';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableDebugTracing = false;
export const enableSchedulingProfiler = false;
export const enableSchedulingProfilerComponentStacks = false;
export const warnAboutDeprecatedLifecycles = true;
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
export const enableProfilerTimer = __PROFILE__;
@@ -13,6 +13,7 @@ import typeof * as ExportsType from './ReactFeatureFlags.test-renderer.www';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableDebugTracing = false;
export const enableSchedulingProfiler = false;
export const enableSchedulingProfilerComponentStacks = false;
export const warnAboutDeprecatedLifecycles = true;
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
export const enableProfilerTimer = __PROFILE__;
@@ -13,6 +13,7 @@ import typeof * as ExportsType from './ReactFeatureFlags.testing';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableDebugTracing = false;
export const enableSchedulingProfiler = false;
export const enableSchedulingProfilerComponentStacks = false;
export const warnAboutDeprecatedLifecycles = true;
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
export const enableProfilerTimer = __PROFILE__;
@@ -13,6 +13,7 @@ import typeof * as ExportsType from './ReactFeatureFlags.testing.www';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableDebugTracing = false;
export const enableSchedulingProfiler = false;
export const enableSchedulingProfilerComponentStacks = false;
export const warnAboutDeprecatedLifecycles = true;
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
export const enableProfilerTimer = false;
@@ -19,9 +19,17 @@ export const enableFilterEmptyStringAttributesDOM = __VARIANT__;
export const enableLegacyFBSupport = __VARIANT__;
export const decoupleUpdatePriorityFromScheduler = __VARIANT__;
// TODO: These features do not currently exist in the new reconciler fork.
export const enableDebugTracing = !__VARIANT__;
export const enableSchedulingProfiler = !__VARIANT__ && __PROFILE__;
// Enable this flag to help with concurrent mode debugging.
// It logs information to the console about React scheduling, rendering, and commit phases.
//
// NOTE: This feature will only work in DEV mode; all callsights are wrapped with __DEV__.
export const enableDebugTracing = false;
// TODO: getStackByFiberInDevAndProd() causes errors when synced to www.
// This flag can be used to disable component stacks for the profiler marks,
// so that the feature can be synced for others,
// while still enabling investigation into the underlying source of the errors.
export const enableSchedulingProfilerComponentStacks = false;
// This only has an effect in the new reconciler. But also, the new reconciler
// is only enabled when __VARIANT__ is true. So this is set to the opposite of
@@ -26,7 +26,7 @@ export const {
deferRenderPhaseUpdateToNextBatch,
decoupleUpdatePriorityFromScheduler,
enableDebugTracing,
enableSchedulingProfiler,
enableSchedulingProfilerComponentStacks,
} = dynamicFeatureFlags;
// On WWW, __EXPERIMENTAL__ is used for a new modern build.
@@ -35,6 +35,9 @@ export const {
export const enableProfilerTimer = __PROFILE__;
export const enableProfilerCommitHooks = __PROFILE__;
// Logs additional User Timing API marks for use with an experimental profiling tool.
export const enableSchedulingProfiler = __PROFILE__;
// Note: we'll want to remove this when we to userland implementation.
// For now, we'll turn it on for everyone because it's *already* on for everyone in practice.
// At least this will let us stop shipping <Profiler> implementation to all users.