Re-enabled DebugTracing feature for old reconciler fork (#19161)
* Re-enabled DebugTracing feature for old reconciler fork It was temporarily removed by @sebmarkbage via PR #18697. Newly re-added tracing is simplified, since the lane(s) data type does not require the (lossy) conversion between priority and expiration time values. @sebmarkbage mentioned that he removed this because it might get in the way of his planned discrete/sync refactor. I'm not sure if that concern still applies, but just in case- I have only re-added it to the old reconciler fork for now. * Force Code Sandbox CI to re-run
Brian Vaughn committed
Jun 23, 2020 at 12:16 UTC
1425fcbb86285a665bb8f42866e8e61efe512923
7 files changed
+187
-45
packages/react-reconciler/src/DebugTracing.js
+17
-12
@@ -7,6 +7,7 @@
7
* @flow
8
*/
9
10
+import type {Lane, Lanes} from './ReactFiberLane';
11
import type {Wakeable} from 'shared/ReactTypes';
12
13
import {enableDebugTracing} from 'shared/ReactFeatureFlags';
@@ -17,6 +18,10 @@ let nativeConsoleLog: null | Function = null;
18
const pendingGroupArgs: Array<any> = [];
19
let printedGroupIndex: number = -1;
20
21
+function formatLanes(laneOrLanes: Lane | Lanes): string {
22
+ return '0b' + (laneOrLanes: any).toString(2).padStart(31, '0');
23
+}
24
+
25
function group(...groupArgs): void {
26
pendingGroupArgs.push(groupArgs);
27
@@ -57,11 +62,11 @@ function log(...logArgs): void {
62
const REACT_LOGO_STYLE =
63
'background-color: #20232a; color: #61dafb; padding: 0 2px;';
64
60
-export function logCommitStarted(priorityLabel: string): void {
65
+export function logCommitStarted(lanes: Lanes): void {
66
if (__DEV__) {
67
if (enableDebugTracing) {
68
group(
64
- `%c⚛️%c commit%c (priority: ${priorityLabel})`,
69
+ `%c⚛️%c commit%c (${formatLanes(lanes)})`,
70
REACT_LOGO_STYLE,
71
'',
72
'font-weight: normal;',
@@ -128,11 +133,11 @@ export function logComponentSuspended(
133
}
134
}
135
131
-export function logLayoutEffectsStarted(priorityLabel: string): void {
136
+export function logLayoutEffectsStarted(lanes: Lanes): void {
137
if (__DEV__) {
138
if (enableDebugTracing) {
139
group(
135
- `%c⚛️%c layout effects%c (priority: ${priorityLabel})`,
140
+ `%c⚛️%c layout effects%c (${formatLanes(lanes)})`,
141
REACT_LOGO_STYLE,
142
'',
143
'font-weight: normal;',
@@ -149,11 +154,11 @@ export function logLayoutEffectsStopped(): void {
154
}
155
}
156
152
-export function logPassiveEffectsStarted(priorityLabel: string): void {
157
+export function logPassiveEffectsStarted(lanes: Lanes): void {
158
if (__DEV__) {
159
if (enableDebugTracing) {
160
group(
156
- `%c⚛️%c passive effects%c (priority: ${priorityLabel})`,
161
+ `%c⚛️%c passive effects%c (${formatLanes(lanes)})`,
162
REACT_LOGO_STYLE,
163
'',
164
'font-weight: normal;',
@@ -170,11 +175,11 @@ export function logPassiveEffectsStopped(): void {
175
}
176
}
177
173
-export function logRenderStarted(priorityLabel: string): void {
178
+export function logRenderStarted(lanes: Lanes): void {
179
if (__DEV__) {
180
if (enableDebugTracing) {
181
group(
177
- `%c⚛️%c render%c (priority: ${priorityLabel})`,
182
+ `%c⚛️%c render%c (${formatLanes(lanes)})`,
183
REACT_LOGO_STYLE,
184
'',
185
'font-weight: normal;',
@@ -193,12 +198,12 @@ export function logRenderStopped(): void {
198
199
export function logForceUpdateScheduled(
200
componentName: string,
196
- priorityLabel: string,
201
+ lane: Lane,
202
): void {
203
if (__DEV__) {
204
if (enableDebugTracing) {
205
log(
201
- `%c⚛️%c ${componentName} forced update %c(priority: ${priorityLabel})`,
206
+ `%c⚛️%c ${componentName} forced update %c(${formatLanes(lane)})`,
207
REACT_LOGO_STYLE,
208
'color: #db2e1f; font-weight: bold;',
209
'',
@@ -209,13 +214,13 @@ export function logForceUpdateScheduled(
214
215
export function logStateUpdateScheduled(
216
componentName: string,
212
- priorityLabel: string,
217
+ lane: Lane,
218
payloadOrAction: any,
219
): void {
220
if (__DEV__) {
221
if (enableDebugTracing) {
222
log(
218
- `%c⚛️%c ${componentName} updated state %c(priority: ${priorityLabel})`,
223
+ `%c⚛️%c ${componentName} updated state %c(${formatLanes(lane)})`,
224
REACT_LOGO_STYLE,
225
'color: #01a252; font-weight: bold;',
226
'',
packages/react-reconciler/src/ReactFiberClassComponent.old.js
+30
-1
@@ -16,6 +16,7 @@ import {Update, Snapshot} from './ReactSideEffectTags';
16
import {
17
debugRenderPhaseSideEffectsForStrictMode,
18
disableLegacyContext,
19
+ enableDebugTracing,
20
warnAboutDeprecatedLifecycles,
21
} from 'shared/ReactFeatureFlags';
22
import ReactStrictModeWarnings from './ReactStrictModeWarnings.old';
@@ -27,7 +28,7 @@ import invariant from 'shared/invariant';
28
import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
29
30
import {resolveDefaultProps} from './ReactFiberLazyComponent.old';
30
-import {StrictMode} from './ReactTypeOfMode';
31
+import {DebugTracingMode, StrictMode} from './ReactTypeOfMode';
32
33
import {
34
enqueueUpdate,
@@ -55,6 +56,7 @@ import {
56
scheduleUpdateOnFiber,
57
} from './ReactFiberWorkLoop.old';
58
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
59
+import {logForceUpdateScheduled, logStateUpdateScheduled} from './DebugTracing';
60
61
import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev';
62
@@ -203,6 +205,15 @@ const classComponentUpdater = {
205
206
enqueueUpdate(fiber, update);
207
scheduleUpdateOnFiber(fiber, lane, eventTime);
208
+
209
+ if (__DEV__) {
210
+ if (enableDebugTracing) {
211
+ if (fiber.mode & DebugTracingMode) {
212
+ const name = getComponentName(fiber.type) || 'Unknown';
213
+ logStateUpdateScheduled(name, lane, payload);
214
+ }
215
+ }
216
+ }
217
},
218
enqueueReplaceState(inst, payload, callback) {
219
const fiber = getInstance(inst);
@@ -223,6 +234,15 @@ const classComponentUpdater = {
234
235
enqueueUpdate(fiber, update);
236
scheduleUpdateOnFiber(fiber, lane, eventTime);
237
+
238
+ if (__DEV__) {
239
+ if (enableDebugTracing) {
240
+ if (fiber.mode & DebugTracingMode) {
241
+ const name = getComponentName(fiber.type) || 'Unknown';
242
+ logStateUpdateScheduled(name, lane, payload);
243
+ }
244
+ }
245
+ }
246
},
247
enqueueForceUpdate(inst, callback) {
248
const fiber = getInstance(inst);
@@ -242,6 +262,15 @@ const classComponentUpdater = {
262
263
enqueueUpdate(fiber, update);
264
scheduleUpdateOnFiber(fiber, lane, eventTime);
265
+
266
+ if (__DEV__) {
267
+ if (enableDebugTracing) {
268
+ if (fiber.mode & DebugTracingMode) {
269
+ const name = getComponentName(fiber.type) || 'Unknown';
270
+ logForceUpdateScheduled(name, lane);
271
+ }
272
+ }
273
+ }
274
},
275
};
276
packages/react-reconciler/src/ReactFiberHooks.old.js
+15
-2
@@ -24,9 +24,12 @@ import type {FiberRoot} from './ReactInternalTypes';
24
import type {OpaqueIDType} from './ReactFiberHostConfig';
25
26
import ReactSharedInternals from 'shared/ReactSharedInternals';
27
-import {enableNewReconciler} from 'shared/ReactFeatureFlags';
27
+import {
28
+ enableDebugTracing,
29
+ enableNewReconciler,
30
+} from 'shared/ReactFeatureFlags';
31
29
-import {NoMode, BlockingMode} from './ReactTypeOfMode';
32
+import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';
33
import {
34
NoLane,
35
NoLanes,
@@ -83,6 +86,7 @@ import {
86
warnAboutMultipleRenderersDEV,
87
} from './ReactMutableSource.old';
88
import {getIsRendering} from './ReactCurrentFiber';
89
+import {logStateUpdateScheduled} from './DebugTracing';
90
91
const {ReactCurrentDispatcher, ReactCurrentBatchConfig} = ReactSharedInternals;
92
@@ -1737,6 +1741,15 @@ function dispatchAction<S, A>(
1741
}
1742
scheduleUpdateOnFiber(fiber, lane, eventTime);
1743
}
1744
+
1745
+ if (__DEV__) {
1746
+ if (enableDebugTracing) {
1747
+ if (fiber.mode & DebugTracingMode) {
1748
+ const name = getComponentName(fiber.type) || 'Unknown';
1749
+ logStateUpdateScheduled(name, lane, action);
1750
+ }
1751
+ }
1752
+ }
1753
}
1754
1755
export const ContextOnlyDispatcher: Dispatcher = {
packages/react-reconciler/src/ReactFiberThrow.old.js
+12
-1
@@ -30,7 +30,8 @@ import {
30
LifecycleEffectMask,
31
} from './ReactSideEffectTags';
32
import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent.old';
33
-import {NoMode, BlockingMode} from './ReactTypeOfMode';
33
+import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';
34
+import {enableDebugTracing} from 'shared/ReactFeatureFlags';
35
import {createCapturedValue} from './ReactCapturedValue';
36
import {
37
enqueueCapturedUpdate,
@@ -53,6 +54,7 @@ import {
54
pingSuspendedRoot,
55
} from './ReactFiberWorkLoop.old';
56
import {logCapturedError} from './ReactFiberErrorLogger';
57
+import {logComponentSuspended} from './DebugTracing';
58
59
import {
60
SyncLane,
@@ -189,6 +191,15 @@ function throwException(
191
// This is a wakeable.
192
const wakeable: Wakeable = (value: any);
193
194
+ if (__DEV__) {
195
+ if (enableDebugTracing) {
196
+ if (sourceFiber.mode & DebugTracingMode) {
197
+ const name = getComponentName(sourceFiber.type) || 'Unknown';
198
+ logComponentSuspended(name, wakeable);
199
+ }
200
+ }
201
+ }
202
+
203
if ((sourceFiber.mode & BlockingMode) === NoMode) {
204
// Reset the memoizedState to what it was before we attempted
205
// to render it.
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+84
@@ -26,6 +26,7 @@ import {
26
enableSchedulerTracing,
27
warnAboutUnmockedScheduler,
28
deferRenderPhaseUpdateToNextBatch,
29
+ enableDebugTracing,
30
} from 'shared/ReactFeatureFlags';
31
import ReactSharedInternals from 'shared/ReactSharedInternals';
32
import invariant from 'shared/invariant';
@@ -45,6 +46,16 @@ import {
46
flushSyncCallbackQueue,
47
scheduleSyncCallback,
48
} from './SchedulerWithReactIntegration.old';
49
+import {
50
+ logCommitStarted,
51
+ logCommitStopped,
52
+ logLayoutEffectsStarted,
53
+ logLayoutEffectsStopped,
54
+ logPassiveEffectsStarted,
55
+ logPassiveEffectsStopped,
56
+ logRenderStarted,
57
+ logRenderStopped,
58
+} from './DebugTracing';
59
60
// The scheduler is imported here *only* to detect whether it's been mocked
61
import * as Scheduler from 'scheduler';
@@ -1444,6 +1455,12 @@ function renderRootSync(root: FiberRoot, lanes: Lanes) {
1455
1456
const prevInteractions = pushInteractions(root);
1457
1458
+ if (__DEV__) {
1459
+ if (enableDebugTracing) {
1460
+ logRenderStarted(lanes);
1461
+ }
1462
+ }
1463
+
1464
do {
1465
try {
1466
workLoopSync();
@@ -1469,6 +1486,12 @@ function renderRootSync(root: FiberRoot, lanes: Lanes) {
1486
);
1487
}
1488
1489
+ if (__DEV__) {
1490
+ if (enableDebugTracing) {
1491
+ logRenderStopped();
1492
+ }
1493
+ }
1494
+
1495
// Set this to null to indicate there's no in-progress render.
1496
workInProgressRoot = null;
1497
workInProgressRootRenderLanes = NoLanes;
@@ -1499,6 +1522,12 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
1522
1523
const prevInteractions = pushInteractions(root);
1524
1525
+ if (__DEV__) {
1526
+ if (enableDebugTracing) {
1527
+ logRenderStarted(lanes);
1528
+ }
1529
+ }
1530
+
1531
do {
1532
try {
1533
workLoopConcurrent();
@@ -1515,6 +1544,12 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
1544
popDispatcher(prevDispatcher);
1545
executionContext = prevExecutionContext;
1546
1547
+ if (__DEV__) {
1548
+ if (enableDebugTracing) {
1549
+ logRenderStopped();
1550
+ }
1551
+ }
1552
+
1553
// Check if the tree has completed.
1554
if (workInProgress !== null) {
1555
// Still work remaining.
@@ -1803,7 +1838,20 @@ function commitRootImpl(root, renderPriorityLevel) {
1838
1839
const finishedWork = root.finishedWork;
1840
const lanes = root.finishedLanes;
1841
+
1842
+ if (__DEV__) {
1843
+ if (enableDebugTracing) {
1844
+ logCommitStarted(lanes);
1845
+ }
1846
+ }
1847
+
1848
if (finishedWork === null) {
1849
+ if (__DEV__) {
1850
+ if (enableDebugTracing) {
1851
+ logCommitStopped();
1852
+ }
1853
+ }
1854
+
1855
return null;
1856
}
1857
root.finishedWork = null;
@@ -2088,6 +2136,12 @@ function commitRootImpl(root, renderPriorityLevel) {
2136
}
2137
2138
if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
2139
+ if (__DEV__) {
2140
+ if (enableDebugTracing) {
2141
+ logCommitStopped();
2142
+ }
2143
+ }
2144
+
2145
// This is a legacy edge case. We just committed the initial mount of
2146
// a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
2147
// synchronously, but layout updates should be deferred until the end
@@ -2098,6 +2152,12 @@ function commitRootImpl(root, renderPriorityLevel) {
2152
// If layout work was scheduled, flush it now.
2153
flushSyncCallbackQueue();
2154
2155
+ if (__DEV__) {
2156
+ if (enableDebugTracing) {
2157
+ logCommitStopped();
2158
+ }
2159
+ }
2160
+
2161
return null;
2162
}
2163
@@ -2222,6 +2282,12 @@ function commitMutationEffects(root: FiberRoot, renderPriorityLevel) {
2282
}
2283
2284
function commitLayoutEffects(root: FiberRoot, committedLanes: Lanes) {
2285
+ if (__DEV__) {
2286
+ if (enableDebugTracing) {
2287
+ logLayoutEffectsStarted(committedLanes);
2288
+ }
2289
+ }
2290
+
2291
// TODO: Should probably move the bulk of this function to commitWork.
2292
while (nextEffect !== null) {
2293
setCurrentDebugFiberInDEV(nextEffect);
@@ -2240,6 +2306,12 @@ function commitLayoutEffects(root: FiberRoot, committedLanes: Lanes) {
2306
resetCurrentDebugFiberInDEV();
2307
nextEffect = nextEffect.nextEffect;
2308
}
2309
+
2310
+ if (__DEV__) {
2311
+ if (enableDebugTracing) {
2312
+ logLayoutEffectsStopped();
2313
+ }
2314
+ }
2315
}
2316
2317
export function flushPassiveEffects() {
@@ -2321,6 +2393,12 @@ function flushPassiveEffectsImpl() {
2393
'Cannot flush passive effects while already rendering.',
2394
);
2395
2396
+ if (__DEV__) {
2397
+ if (enableDebugTracing) {
2398
+ logPassiveEffectsStarted(lanes);
2399
+ }
2400
+ }
2401
+
2402
if (__DEV__) {
2403
isFlushingPassiveEffects = true;
2404
}
@@ -2477,6 +2555,12 @@ function flushPassiveEffectsImpl() {
2555
isFlushingPassiveEffects = false;
2556
}
2557
2558
+ if (__DEV__) {
2559
+ if (enableDebugTracing) {
2560
+ logPassiveEffectsStopped();
2561
+ }
2562
+ }
2563
+
2564
executionContext = prevExecutionContext;
2565
2566
flushSyncCallbackQueue();
packages/react-reconciler/src/__tests__/DebugTracing-test.internal.js
+27
-27
@@ -85,9 +85,9 @@ describe('DebugTracing', () => {
85
);
86
87
expect(logs).toEqual([
88
- 'group: ⚛️ render (priority: immediate)',
88
+ 'group: ⚛️ render (0b0000000000000000000000000000001)',
89
'log: ⚛️ Example suspended',
90
- 'groupEnd: ⚛️ render (priority: immediate)',
90
+ 'groupEnd: ⚛️ render (0b0000000000000000000000000000001)',
91
]);
92
93
logs.splice(0);
@@ -119,9 +119,9 @@ describe('DebugTracing', () => {
119
expect(Scheduler).toFlushUntilNextPaint([]);
120
121
expect(logs).toEqual([
122
- 'group: ⚛️ render (priority: normal)',
122
+ 'group: ⚛️ render (0b0000000000000000000001000000000)',
123
'log: ⚛️ Example suspended',
124
- 'groupEnd: ⚛️ render (priority: normal)',
124
+ 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)',
125
]);
126
127
logs.splice(0);
@@ -156,11 +156,11 @@ describe('DebugTracing', () => {
156
expect(Scheduler).toFlushUntilNextPaint([]);
157
158
expect(logs).toEqual([
159
- 'group: ⚛️ commit (priority: normal)',
160
- 'group: ⚛️ layout effects (priority: immediate)',
161
- 'log: ⚛️ Example updated state (priority: immediate)',
162
- 'groupEnd: ⚛️ layout effects (priority: immediate)',
163
- 'groupEnd: ⚛️ commit (priority: normal)',
159
+ 'group: ⚛️ commit (0b0000000000000000000001000000000)',
160
+ 'group: ⚛️ layout effects (0b0000000000000000000001000000000)',
161
+ 'log: ⚛️ Example updated state (0b0000000000000000000000000000001)',
162
+ 'groupEnd: ⚛️ layout effects (0b0000000000000000000001000000000)',
163
+ 'groupEnd: ⚛️ commit (0b0000000000000000000001000000000)',
164
]);
165
});
166
@@ -192,10 +192,10 @@ describe('DebugTracing', () => {
192
}).toErrorDev('Cannot update during an existing state transition');
193
194
expect(logs).toEqual([
195
- 'group: ⚛️ render (priority: normal)',
196
- 'log: ⚛️ Example updated state (priority: normal)',
197
- 'log: ⚛️ Example updated state (priority: normal)',
198
- 'groupEnd: ⚛️ render (priority: normal)',
195
+ 'group: ⚛️ render (0b0000000000000000000001000000000)',
196
+ 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)',
197
+ 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)',
198
+ 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)',
199
]);
200
});
201
@@ -223,11 +223,11 @@ describe('DebugTracing', () => {
223
expect(Scheduler).toFlushUntilNextPaint([]);
224
225
expect(logs).toEqual([
226
- 'group: ⚛️ commit (priority: normal)',
227
- 'group: ⚛️ layout effects (priority: immediate)',
228
- 'log: ⚛️ Example updated state (priority: immediate)',
229
- 'groupEnd: ⚛️ layout effects (priority: immediate)',
230
- 'groupEnd: ⚛️ commit (priority: normal)',
226
+ 'group: ⚛️ commit (0b0000000000000000000001000000000)',
227
+ 'group: ⚛️ layout effects (0b0000000000000000000001000000000)',
228
+ 'log: ⚛️ Example updated state (0b0000000000000000000000000000001)',
229
+ 'groupEnd: ⚛️ layout effects (0b0000000000000000000001000000000)',
230
+ 'groupEnd: ⚛️ commit (0b0000000000000000000001000000000)',
231
]);
232
});
233
@@ -250,9 +250,9 @@ describe('DebugTracing', () => {
250
);
251
});
252
expect(logs).toEqual([
253
- 'group: ⚛️ passive effects (priority: normal)',
254
- 'log: ⚛️ Example updated state (priority: normal)',
255
- 'groupEnd: ⚛️ passive effects (priority: normal)',
253
+ 'group: ⚛️ passive effects (0b0000000000000000000001000000000)',
254
+ 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)',
255
+ 'groupEnd: ⚛️ passive effects (0b0000000000000000000001000000000)',
256
]);
257
});
258
@@ -275,10 +275,10 @@ describe('DebugTracing', () => {
275
);
276
});
277
expect(logs).toEqual([
278
- 'group: ⚛️ render (priority: normal)',
279
- 'log: ⚛️ Example updated state (priority: normal)',
280
- 'log: ⚛️ Example updated state (priority: normal)', // debugRenderPhaseSideEffectsForStrictMode
281
- 'groupEnd: ⚛️ render (priority: normal)',
278
+ 'group: ⚛️ render (0b0000000000000000000001000000000)',
279
+ 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)',
280
+ 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)', // debugRenderPhaseSideEffectsForStrictMode
281
+ 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)',
282
]);
283
});
284
@@ -303,9 +303,9 @@ describe('DebugTracing', () => {
303
expect(Scheduler).toFlushUntilNextPaint([]);
304
305
expect(logs).toEqual([
306
- 'group: ⚛️ render (priority: normal)',
306
+ 'group: ⚛️ render (0b0000000000000000000001000000000)',
307
'log: Hello from user code',
308
- 'groupEnd: ⚛️ render (priority: normal)',
308
+ 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)',
309
]);
310
});
311
packages/shared/forks/ReactFeatureFlags.www.js
+2
-2
@@ -78,8 +78,8 @@ export const enableModernEventSystem = true;
78
// to the correct value.
79
export const enableNewReconciler = __VARIANT__;
80
81
-// TODO: This does not currently exist in the Lanes implementation.
82
-export const enableDebugTracing = false;
81
+// TODO: This does not currently exist in the new reconciler fork.
82
+export const enableDebugTracing = !__VARIANT__;
83
84
// Flow magic to verify the exports of this file match the original version.
85
// eslint-disable-next-line no-unused-vars