Skip to content

Commit fa0d5b1

Browse files
author
Brian Vaughn
committed
Added separate feature flag for scheduler tracking
1 parent daf9abf commit fa0d5b1

12 files changed

+93
-55
lines changed

packages/react-reconciler/src/ReactFiberCommitWork.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
enableSchedulerTracing,
2929
enableProfilerTimer,
3030
enableSuspenseServerRenderer,
31+
enableUpdateSchedulerTracking,
3132
enableEventAPI,
3233
} from 'shared/ReactFeatureFlags';
3334
import {
@@ -1334,11 +1335,18 @@ function commitSuspenseComponent(
13341335
}
13351336
thenables.forEach(thenable => {
13361337
// Memoize using the boundary fiber to prevent redundant listeners.
1337-
let retry = resolveRetryThenable.bind(null, finishedWork, thenable);
1338+
let retry = resolveRetryThenable.bind(
1339+
null,
1340+
finishedWork,
1341+
thenable,
1342+
finishedRoot,
1343+
committedExpirationTime,
1344+
);
13381345
if (!retryCache.has(thenable)) {
13391346
if (enableSchedulerTracing) {
13401347
retry = Schedule_tracing_wrap(retry);
1341-
1348+
}
1349+
if (enableUpdateSchedulerTracking) {
13421350
// If we have pending work still, restore the original schedulers
13431351
restorePendingSchedulers(finishedRoot, committedExpirationTime);
13441352
}

packages/react-reconciler/src/ReactFiberRoot.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ import type {Interaction} from 'scheduler/src/Tracing';
1717
import {noTimeout} from './ReactFiberHostConfig';
1818
import {createHostRootFiber} from './ReactFiber';
1919
import {NoWork} from './ReactFiberExpirationTime';
20-
import {enableSchedulerTracing} from 'shared/ReactFeatureFlags';
20+
import {
21+
enableSchedulerTracing,
22+
enableUpdateSchedulerTracking,
23+
} from 'shared/ReactFeatureFlags';
2124
import {unstable_getThreadID} from 'scheduler/tracing';
2225

2326
// TODO: This should be lifted into the renderer.
@@ -84,9 +87,11 @@ type ProfilingOnlyFiberRootProperties = {|
8487
interactionThreadID: number,
8588
memoizedInteractions: Set<Interaction>,
8689
pendingInteractionMap: PendingInteractionMap,
90+
|};
8791

88-
// Used to enable DevTools Profiler UI to show which Fibers scheduled a given commit.
89-
// May also be useful in the future to expose via the Profiler API somehow?
92+
// The following attributes are only used by DevTools and are only present in DEV builds.
93+
// They enable DevTools Profiler UI to show which Fiber(s) scheduled a given commit.
94+
type SchedulerTrackingOnlyFiberRootProperties = {|
9095
memoizedSchedulers: Set<Fiber>,
9196
pendingSchedulersMap: PendingSchedulersMap,
9297
|};
@@ -99,6 +104,7 @@ type ProfilingOnlyFiberRootProperties = {|
99104
export type FiberRoot = {
100105
...BaseFiberRootProperties,
101106
...ProfilingOnlyFiberRootProperties,
107+
...SchedulerTrackingOnlyFiberRootProperties,
102108
};
103109

104110
function FiberRootNode(containerInfo, tag, hydrate) {
@@ -124,6 +130,9 @@ function FiberRootNode(containerInfo, tag, hydrate) {
124130
this.interactionThreadID = unstable_getThreadID();
125131
this.memoizedInteractions = new Set();
126132
this.pendingInteractionMap = new Map();
133+
}
134+
135+
if (enableUpdateSchedulerTracking) {
127136
this.memoizedSchedulers = new Set();
128137
this.pendingSchedulersMap = new Map();
129138
}

packages/react-reconciler/src/ReactFiberScheduler.js

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type {Interaction} from 'scheduler/src/Tracing';
1919
import {
2020
warnAboutDeprecatedLifecycles,
2121
enableUserTimingAPI,
22+
enableUpdateSchedulerTracking,
2223
enableSuspenseServerRenderer,
2324
replayFailedUnitOfWorkWithInvokeGuardedCallback,
2425
enableProfilerTimer,
@@ -336,7 +337,7 @@ export function scheduleUpdateOnFiber(
336337
return;
337338
}
338339

339-
if (enableSchedulerTracing) {
340+
if (enableUpdateSchedulerTracking) {
340341
const pendingSchedulersMap = root.pendingSchedulersMap;
341342
let schedulers = pendingSchedulersMap.get(expirationTime);
342343
if (schedulers == null) {
@@ -2179,6 +2180,10 @@ export function restorePendingSchedulers(
21792180
root: FiberRoot,
21802181
expirationTime: ExpirationTime,
21812182
): void {
2183+
if (!enableUpdateSchedulerTracking) {
2184+
return;
2185+
}
2186+
21822187
const pendingSchedulersMap = root.pendingSchedulersMap;
21832188
let schedulers = pendingSchedulersMap.get(expirationTime);
21842189
if (schedulers == null) {
@@ -2306,52 +2311,54 @@ function schedulePendingInteraction(root, expirationTime) {
23062311

23072312
function startWorkOnPendingInteraction(root, expirationTime) {
23082313
// This is called when new work is started on a root.
2309-
if (!enableSchedulerTracing) {
2310-
return;
2311-
}
23122314

2313-
// Determine which interactions this batch of work currently includes, So that
2314-
// we can accurately attribute time spent working on it, And so that cascading
2315-
// work triggered during the render phase will be associated with it.
2316-
const interactions: Set<Interaction> = new Set();
2317-
root.pendingInteractionMap.forEach(
2318-
(scheduledInteractions, scheduledExpirationTime) => {
2315+
if (enableUpdateSchedulerTracking) {
2316+
const memoizedSchedulers: Set<Fiber> = new Set();
2317+
const pendingSchedulersMap = root.pendingSchedulersMap;
2318+
pendingSchedulersMap.forEach((schedulers, scheduledExpirationTime) => {
23192319
if (scheduledExpirationTime >= expirationTime) {
2320-
scheduledInteractions.forEach(interaction =>
2321-
interactions.add(interaction),
2322-
);
2320+
pendingSchedulersMap.delete(scheduledExpirationTime);
2321+
schedulers.forEach(fiber => memoizedSchedulers.add(fiber));
23232322
}
2324-
},
2325-
);
2323+
});
23262324

2327-
const memoizedSchedulers: Set<Fiber> = new Set();
2328-
const pendingSchedulersMap = root.pendingSchedulersMap;
2329-
pendingSchedulersMap.forEach((schedulers, scheduledExpirationTime) => {
2330-
if (scheduledExpirationTime >= expirationTime) {
2331-
pendingSchedulersMap.delete(scheduledExpirationTime);
2332-
schedulers.forEach(fiber => memoizedSchedulers.add(fiber));
2333-
}
2334-
});
2325+
root.memoizedSchedulers = memoizedSchedulers;
2326+
}
23352327

2336-
// Store the current set of interactions on the FiberRoot for a few reasons:
2337-
// We can re-use it in hot functions like renderRoot() without having to
2338-
// recalculate it. We will also use it in commitWork() to pass to any Profiler
2339-
// onRender() hooks. This also provides DevTools with a way to access it when
2340-
// the onCommitRoot() hook is called.
2341-
root.memoizedInteractions = interactions;
2342-
root.memoizedSchedulers = memoizedSchedulers;
2328+
if (enableSchedulerTracing) {
2329+
// Determine which interactions this batch of work currently includes, So that
2330+
// we can accurately attribute time spent working on it, And so that cascading
2331+
// work triggered during the render phase will be associated with it.
2332+
const interactions: Set<Interaction> = new Set();
2333+
root.pendingInteractionMap.forEach(
2334+
(scheduledInteractions, scheduledExpirationTime) => {
2335+
if (scheduledExpirationTime >= expirationTime) {
2336+
scheduledInteractions.forEach(interaction =>
2337+
interactions.add(interaction),
2338+
);
2339+
}
2340+
},
2341+
);
23432342

2344-
if (interactions.size > 0) {
2345-
const subscriber = __subscriberRef.current;
2346-
if (subscriber !== null) {
2347-
const threadID = computeThreadID(root, expirationTime);
2348-
try {
2349-
subscriber.onWorkStarted(interactions, threadID);
2350-
} catch (error) {
2351-
// If the subscriber throws, rethrow it in a separate task
2352-
scheduleCallback(ImmediatePriority, () => {
2353-
throw error;
2354-
});
2343+
// Store the current set of interactions on the FiberRoot for a few reasons:
2344+
// We can re-use it in hot functions like renderRoot() without having to
2345+
// recalculate it. We will also use it in commitWork() to pass to any Profiler
2346+
// onRender() hooks. This also provides DevTools with a way to access it when
2347+
// the onCommitRoot() hook is called.
2348+
root.memoizedInteractions = interactions;
2349+
2350+
if (interactions.size > 0) {
2351+
const subscriber = __subscriberRef.current;
2352+
if (subscriber !== null) {
2353+
const threadID = computeThreadID(root, expirationTime);
2354+
try {
2355+
subscriber.onWorkStarted(interactions, threadID);
2356+
} catch (error) {
2357+
// If the subscriber throws, rethrow it in a separate task
2358+
scheduleCallback(ImmediatePriority, () => {
2359+
throw error;
2360+
});
2361+
}
23552362
}
23562363
}
23572364
}

packages/react-reconciler/src/ReactFiberUnwindWork.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
import {
4141
enableSchedulerTracing,
4242
enableSuspenseServerRenderer,
43+
enableUpdateSchedulerTracking,
4344
enableEventAPI,
4445
} from 'shared/ReactFeatureFlags';
4546
import {NoMode, BatchedMode} from './ReactTypeOfMode';
@@ -187,7 +188,8 @@ function attachPingListener(
187188
);
188189
if (enableSchedulerTracing) {
189190
ping = Schedule_tracing_wrap(ping);
190-
191+
}
192+
if (enableUpdateSchedulerTracking) {
191193
// If we have pending work still, restore the original schedulers
192194
restorePendingSchedulers(root, renderExpirationTime);
193195
}
@@ -319,10 +321,17 @@ function throwException(
319321
// Memoize using the boundary fiber to prevent redundant listeners.
320322
if (!retryCache.has(thenable)) {
321323
retryCache.add(thenable);
322-
let retry = resolveRetryThenable.bind(null, workInProgress, thenable);
324+
let retry = resolveRetryThenable.bind(
325+
null,
326+
workInProgress,
327+
thenable,
328+
root,
329+
renderExpirationTime,
330+
);
323331
if (enableSchedulerTracing) {
324332
retry = Schedule_tracing_wrap(retry);
325-
333+
}
334+
if (enableUpdateSchedulerTracking) {
326335
// If we have pending work still, restore the original schedulers
327336
restorePendingSchedulers(root, renderExpirationTime);
328337
}

packages/react-reconciler/src/__tests__/ReactSchedulers-test.internal.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ let Scheduler;
1616
let TestUtils;
1717
let mockDevToolsHook;
1818

19-
function loadModules({
20-
enableProfilerTimer = true,
21-
enableSchedulerTracing = true,
22-
} = {}) {
19+
function loadModules(enableUpdateSchedulerTracking = true) {
2320
jest.resetModules();
2421

2522
mockDevToolsHook = {
@@ -35,8 +32,7 @@ function loadModules({
3532
);
3633

3734
ReactFeatureFlags = require('shared/ReactFeatureFlags');
38-
ReactFeatureFlags.enableProfilerTimer = enableProfilerTimer;
39-
ReactFeatureFlags.enableSchedulerTracing = enableSchedulerTracing;
35+
ReactFeatureFlags.enableUpdateSchedulerTracking = enableUpdateSchedulerTracking;
4036

4137
React = require('react');
4238
ReactDOM = require('react-dom');

packages/shared/ReactFeatureFlags.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ export const enableProfilerTimer = __PROFILE__;
3131
// Trace which interactions trigger each commit.
3232
export const enableSchedulerTracing = __PROFILE__;
3333

34+
// Track which Fiber(s) schedule render work.
35+
export const enableUpdateSchedulerTracking = __PROFILE__;
36+
3437
// Only used in www builds.
3538
export const enableSuspenseServerRenderer = false; // TODO: __DEV__? Here it might just be false.
3639

packages/shared/forks/ReactFeatureFlags.native-fb.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const {debugRenderPhaseSideEffects} = require('ReactFeatureFlags');
1919
export const enableUserTimingAPI = __DEV__;
2020
export const enableProfilerTimer = __PROFILE__;
2121
export const enableSchedulerTracing = __PROFILE__;
22+
export const enableUpdateSchedulerTracking = __PROFILE__;
2223
export const enableSuspenseServerRenderer = false;
2324
export const enableStableConcurrentModeAPIs = false;
2425
export const warnAboutShorthandPropertyCollision = false;

packages/shared/forks/ReactFeatureFlags.native-oss.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
1919
export const warnAboutDeprecatedLifecycles = true;
2020
export const enableProfilerTimer = __PROFILE__;
2121
export const enableSchedulerTracing = __PROFILE__;
22+
export const enableUpdateSchedulerTracking = __PROFILE__;
2223
export const enableSuspenseServerRenderer = false;
2324
export const disableJavaScriptURLs = false;
2425
export const disableYielding = false;

packages/shared/forks/ReactFeatureFlags.persistent.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const warnAboutDeprecatedLifecycles = true;
1919
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
2020
export const enableProfilerTimer = __PROFILE__;
2121
export const enableSchedulerTracing = __PROFILE__;
22+
export const enableUpdateSchedulerTracking = __PROFILE__;
2223
export const enableSuspenseServerRenderer = false;
2324
export const disableJavaScriptURLs = false;
2425
export const disableYielding = false;

packages/shared/forks/ReactFeatureFlags.test-renderer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const warnAboutDeprecatedLifecycles = false;
1919
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
2020
export const enableProfilerTimer = false;
2121
export const enableSchedulerTracing = false;
22+
export const enableUpdateSchedulerTracking = false;
2223
export const enableSuspenseServerRenderer = false;
2324
export const disableJavaScriptURLs = false;
2425
export const disableYielding = false;

packages/shared/forks/ReactFeatureFlags.test-renderer.www.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const warnAboutDeprecatedLifecycles = true;
1919
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
2020
export const enableProfilerTimer = false;
2121
export const enableSchedulerTracing = false;
22+
export const enableUpdateSchedulerTracking = false;
2223
export const enableSuspenseServerRenderer = false;
2324
export const enableStableConcurrentModeAPIs = false;
2425
export const enableSchedulerDebugging = false;

packages/shared/forks/ReactFeatureFlags.www.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export let enableUserTimingAPI = __DEV__;
3232

3333
export const enableProfilerTimer = __PROFILE__;
3434
export const enableSchedulerTracing = __PROFILE__;
35+
export const enableUpdateSchedulerTracking = __PROFILE__;
3536
export const enableSchedulerDebugging = true;
3637

3738
export const enableStableConcurrentModeAPIs = false;

0 commit comments

Comments
 (0)