@samitouri / QOS-React-2 / commits / cc7c1aece4

Re-enabled DebugTracing feature for old reconciler fork (#19142)

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.

Brian Vaughn committed Jun 16, 2020 at 15:16 UTC cc7c1aece46a6b69b41958d731e0fd27c94bfc6c
7 files changed +189 -47
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
+86 -2
@@ -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.
@@ -1785,6 +1820,15 @@ function commitRoot(root) {
1820 }
1821
1822 function commitRootImpl(root, renderPriorityLevel) {
1823 + const finishedWork = root.finishedWork;
1824 + const lanes = root.finishedLanes;
1825 +
1826 + if (__DEV__) {
1827 + if (enableDebugTracing) {
1828 + logCommitStarted(lanes);
1829 + }
1830 + }
1831 +
1832 do {
1833 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
1834 // means `flushPassiveEffects` will sometimes result in additional
@@ -1801,9 +1845,13 @@ function commitRootImpl(root, renderPriorityLevel) {
1845 'Should not already be working.',
1846 );
1847
1804 - const finishedWork = root.finishedWork;
1805 - const lanes = root.finishedLanes;
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