Skip to content

Commit 7a27ebd

Browse files
authored
Update user timing to record when we are about to commit (#12384)
* Update user timing to record when we are about to commit **what is the change?:** After repeatedly logging '(React Tree Reconciliation)' we vary the message slightly for the last reconciliation, which happens right before we commit. **why make this change?:** When debugging performance in the devtools it will be helpful if we can quickly see where the 'commit' happens in a potentially long list of sliced '(React Tree Reconciliation)' logs. **test plan:** Built and ran one of the fixtures. Also ran the unit test. (Flarnie will insert a screenshot) * Ran prettier * Fixes in response to code review * Update snapshot tests * Move isWorking assignment out of branches to top * Stricter type for stopWorkLoopTimer args
1 parent 6b99c6f commit 7a27ebd

File tree

3 files changed

+53
-43
lines changed

3 files changed

+53
-43
lines changed

packages/react-reconciler/src/ReactDebugFiberPerf.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,10 @@ export function startWorkLoopTimer(nextUnitOfWork: Fiber | null): void {
369369
}
370370
}
371371

372-
export function stopWorkLoopTimer(interruptedBy: Fiber | null): void {
372+
export function stopWorkLoopTimer(
373+
interruptedBy: Fiber | null,
374+
didCompleteRoot: boolean,
375+
): void {
373376
if (enableUserTimingAPI) {
374377
if (!supportsUserTiming) {
375378
return;
@@ -388,13 +391,12 @@ export function stopWorkLoopTimer(interruptedBy: Fiber | null): void {
388391
warning = 'There were cascading updates';
389392
}
390393
commitCountInCurrentWorkLoop = 0;
394+
let label = didCompleteRoot
395+
? '(React Tree Reconciliation: Completed Root)'
396+
: '(React Tree Reconciliation: Yielded)';
391397
// Pause any measurements until the next loop.
392398
pauseTimers();
393-
endMark(
394-
'(React Tree Reconciliation)',
395-
'(React Tree Reconciliation)',
396-
warning,
397-
);
399+
endMark(label, '(React Tree Reconciliation)', warning);
398400
}
399401
}
400402

packages/react-reconciler/src/ReactFiberScheduler.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -958,12 +958,13 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
958958
} while (true);
959959

960960
// We're done performing work. Time to clean up.
961-
stopWorkLoopTimer(interruptedBy);
962-
interruptedBy = null;
961+
let didCompleteRoot = false;
963962
isWorking = false;
964963

965964
// Yield back to main thread.
966965
if (didFatal) {
966+
stopWorkLoopTimer(interruptedBy, didCompleteRoot);
967+
interruptedBy = null;
967968
// There was a fatal error.
968969
if (__DEV__) {
969970
stack.resetStackAfterFatalErrorInDev();
@@ -972,19 +973,26 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
972973
} else if (nextUnitOfWork === null) {
973974
// We reached the root.
974975
if (isRootReadyForCommit) {
976+
didCompleteRoot = true;
977+
stopWorkLoopTimer(interruptedBy, didCompleteRoot);
978+
interruptedBy = null;
975979
// The root successfully completed. It's ready for commit.
976980
root.pendingCommitExpirationTime = expirationTime;
977981
const finishedWork = root.current.alternate;
978982
return finishedWork;
979983
} else {
980984
// The root did not complete.
985+
stopWorkLoopTimer(interruptedBy, didCompleteRoot);
986+
interruptedBy = null;
981987
invariant(
982988
false,
983989
'Expired work should have completed. This error is likely caused ' +
984990
'by a bug in React. Please file an issue.',
985991
);
986992
}
987993
} else {
994+
stopWorkLoopTimer(interruptedBy, didCompleteRoot);
995+
interruptedBy = null;
988996
// There's more work to do, but we ran out of time. Yield back to
989997
// the renderer.
990998
return null;

packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ exports[`ReactDebugFiberPerf captures all lifecycles 1`] = `
44
"⚛ (Waiting for async callback... will force flush in 5230 ms)
55
66
// Mount
7-
⚛ (React Tree Reconciliation)
7+
⚛ (React Tree Reconciliation: Completed Root)
88
⚛ AllLifecycles [mount]
99
⚛ AllLifecycles.componentWillMount
1010
⚛ AllLifecycles.getChildContext
@@ -18,7 +18,7 @@ exports[`ReactDebugFiberPerf captures all lifecycles 1`] = `
1818
⚛ (Waiting for async callback... will force flush in 5230 ms)
1919
2020
// Update
21-
⚛ (React Tree Reconciliation)
21+
⚛ (React Tree Reconciliation: Completed Root)
2222
⚛ AllLifecycles [update]
2323
⚛ AllLifecycles.componentWillReceiveProps
2424
⚛ AllLifecycles.shouldComponentUpdate
@@ -34,7 +34,7 @@ exports[`ReactDebugFiberPerf captures all lifecycles 1`] = `
3434
⚛ (Waiting for async callback... will force flush in 5230 ms)
3535
3636
// Unmount
37-
⚛ (React Tree Reconciliation)
37+
⚛ (React Tree Reconciliation: Completed Root)
3838
3939
⚛ (Committing Changes)
4040
⚛ (Committing Snapshot Effects: 0 Total)
@@ -48,7 +48,7 @@ exports[`ReactDebugFiberPerf deduplicates lifecycle names during commit to reduc
4848
"⚛ (Waiting for async callback... will force flush in 5230 ms)
4949
5050
// The commit phase should mention A and B just once
51-
⚛ (React Tree Reconciliation)
51+
⚛ (React Tree Reconciliation: Completed Root)
5252
⚛ Parent [update]
5353
⚛ A [update]
5454
⚛ B [update]
@@ -66,7 +66,7 @@ exports[`ReactDebugFiberPerf deduplicates lifecycle names during commit to reduc
6666
6767
// Because of deduplication, we don't know B was cascading,
6868
// but we should still see the warning for the commit phase.
69-
⚛ (React Tree Reconciliation)
69+
⚛ (React Tree Reconciliation: Completed Root)
7070
⚛ Parent [update]
7171
⚛ A [update]
7272
⚛ B [update]
@@ -80,7 +80,7 @@ exports[`ReactDebugFiberPerf deduplicates lifecycle names during commit to reduc
8080
⚛ A.componentDidUpdate
8181
⚛ B.componentDidUpdate
8282
83-
⚛ (React Tree Reconciliation)
83+
⚛ (React Tree Reconciliation: Completed Root)
8484
⚛ B [update]
8585
8686
⚛ (Committing Changes)
@@ -92,7 +92,7 @@ exports[`ReactDebugFiberPerf deduplicates lifecycle names during commit to reduc
9292
`;
9393

9494
exports[`ReactDebugFiberPerf does not schedule an extra callback if setState is called during a synchronous commit phase 1`] = `
95-
"⚛ (React Tree Reconciliation)
95+
"⚛ (React Tree Reconciliation: Completed Root)
9696
⚛ Component [mount]
9797
9898
⛔ (Committing Changes) Warning: Lifecycle hook scheduled a cascading update
@@ -101,7 +101,7 @@ exports[`ReactDebugFiberPerf does not schedule an extra callback if setState is
101101
⚛ (Calling Lifecycle Methods: 1 Total)
102102
⛔ Component.componentDidMount Warning: Scheduled a cascading update
103103
104-
⚛ (React Tree Reconciliation)
104+
⚛ (React Tree Reconciliation: Completed Root)
105105
⚛ Component [update]
106106
107107
⚛ (Committing Changes)
@@ -115,7 +115,7 @@ exports[`ReactDebugFiberPerf does not treat setState from cWM or cWRP as cascadi
115115
"⚛ (Waiting for async callback... will force flush in 5230 ms)
116116
117117
// Should not print a warning
118-
⚛ (React Tree Reconciliation)
118+
⚛ (React Tree Reconciliation: Completed Root)
119119
⚛ Parent [mount]
120120
⚛ NotCascading [mount]
121121
⚛ NotCascading.componentWillMount
@@ -128,7 +128,7 @@ exports[`ReactDebugFiberPerf does not treat setState from cWM or cWRP as cascadi
128128
⚛ (Waiting for async callback... will force flush in 5230 ms)
129129
130130
// Should not print a warning
131-
⚛ (React Tree Reconciliation)
131+
⚛ (React Tree Reconciliation: Completed Root)
132132
⚛ Parent [update]
133133
⚛ NotCascading [update]
134134
⚛ NotCascading.componentWillReceiveProps
@@ -144,7 +144,7 @@ exports[`ReactDebugFiberPerf measures a simple reconciliation 1`] = `
144144
"⚛ (Waiting for async callback... will force flush in 5230 ms)
145145
146146
// Mount
147-
⚛ (React Tree Reconciliation)
147+
⚛ (React Tree Reconciliation: Completed Root)
148148
⚛ Parent [mount]
149149
⚛ Child [mount]
150150
@@ -156,7 +156,7 @@ exports[`ReactDebugFiberPerf measures a simple reconciliation 1`] = `
156156
⚛ (Waiting for async callback... will force flush in 5230 ms)
157157
158158
// Update
159-
⚛ (React Tree Reconciliation)
159+
⚛ (React Tree Reconciliation: Completed Root)
160160
⚛ Parent [update]
161161
⚛ Child [update]
162162
@@ -168,7 +168,7 @@ exports[`ReactDebugFiberPerf measures a simple reconciliation 1`] = `
168168
⚛ (Waiting for async callback... will force flush in 5230 ms)
169169
170170
// Unmount
171-
⚛ (React Tree Reconciliation)
171+
⚛ (React Tree Reconciliation: Completed Root)
172172
173173
⚛ (Committing Changes)
174174
⚛ (Committing Snapshot Effects: 0 Total)
@@ -181,22 +181,22 @@ exports[`ReactDebugFiberPerf measures deferred work in chunks 1`] = `
181181
"⚛ (Waiting for async callback... will force flush in 5230 ms)
182182
183183
// Start mounting Parent and A
184-
⚛ (React Tree Reconciliation)
184+
⚛ (React Tree Reconciliation: Yielded)
185185
⚛ Parent [mount]
186186
⚛ A [mount]
187187
⚛ Child [mount]
188188
189189
⚛ (Waiting for async callback... will force flush in 5230 ms)
190190
191191
// Mount B just a little (but not enough to memoize)
192-
⚛ (React Tree Reconciliation)
192+
⚛ (React Tree Reconciliation: Yielded)
193193
⚛ Parent [mount]
194194
⚛ B [mount]
195195
196196
⚛ (Waiting for async callback... will force flush in 5230 ms)
197197
198198
// Complete B and Parent
199-
⚛ (React Tree Reconciliation)
199+
⚛ (React Tree Reconciliation: Completed Root)
200200
⚛ Parent [mount]
201201
⚛ B [mount]
202202
⚛ Child [mount]
@@ -210,7 +210,7 @@ exports[`ReactDebugFiberPerf measures deferred work in chunks 1`] = `
210210

211211
exports[`ReactDebugFiberPerf measures deprioritized work 1`] = `
212212
"// Flush the parent
213-
⚛ (React Tree Reconciliation)
213+
⚛ (React Tree Reconciliation: Completed Root)
214214
⚛ Parent [mount]
215215
216216
⚛ (Committing Changes)
@@ -221,7 +221,7 @@ exports[`ReactDebugFiberPerf measures deprioritized work 1`] = `
221221
⚛ (Waiting for async callback... will force flush in 10737418210 ms)
222222
223223
// Flush the child
224-
⚛ (React Tree Reconciliation)
224+
⚛ (React Tree Reconciliation: Completed Root)
225225
⚛ Child [mount]
226226
227227
⚛ (Committing Changes)
@@ -235,13 +235,13 @@ exports[`ReactDebugFiberPerf recovers from caught errors 1`] = `
235235
"⚛ (Waiting for async callback... will force flush in 5230 ms)
236236
237237
// Stop on Baddie and restart from Boundary
238-
⚛ (React Tree Reconciliation)
238+
⚛ (React Tree Reconciliation: Yielded)
239239
⚛ Parent [mount]
240240
⛔ Boundary [mount] Warning: An error was thrown inside this error boundary
241241
⚛ Parent [mount]
242242
⚛ Baddie [mount]
243243
244-
⚛ (React Tree Reconciliation)
244+
⚛ (React Tree Reconciliation: Completed Root)
245245
⚛ Parent [mount]
246246
⚛ Boundary [mount]
247247
@@ -250,7 +250,7 @@ exports[`ReactDebugFiberPerf recovers from caught errors 1`] = `
250250
⚛ (Committing Host Effects: 2 Total)
251251
⚛ (Calling Lifecycle Methods: 0 Total)
252252
253-
⚛ (React Tree Reconciliation)
253+
⚛ (React Tree Reconciliation: Completed Root)
254254
⚛ Boundary [update]
255255
⚛ ErrorReport [mount]
256256
@@ -265,11 +265,11 @@ exports[`ReactDebugFiberPerf recovers from fatal errors 1`] = `
265265
"⚛ (Waiting for async callback... will force flush in 5230 ms)
266266
267267
// Will fatal
268-
⚛ (React Tree Reconciliation)
268+
⚛ (React Tree Reconciliation: Yielded)
269269
⚛ Parent [mount]
270270
⚛ Baddie [mount]
271271
272-
⚛ (React Tree Reconciliation)
272+
⚛ (React Tree Reconciliation: Completed Root)
273273
274274
⚛ (Committing Changes)
275275
⚛ (Committing Snapshot Effects: 0 Total)
@@ -279,7 +279,7 @@ exports[`ReactDebugFiberPerf recovers from fatal errors 1`] = `
279279
⚛ (Waiting for async callback... will force flush in 5230 ms)
280280
281281
// Will reconcile from a clean state
282-
⚛ (React Tree Reconciliation)
282+
⚛ (React Tree Reconciliation: Completed Root)
283283
⚛ Parent [mount]
284284
⚛ Child [mount]
285285
@@ -294,7 +294,7 @@ exports[`ReactDebugFiberPerf skips parents during setState 1`] = `
294294
"⚛ (Waiting for async callback... will force flush in 5230 ms)
295295
296296
// Should include just A and B, no Parents
297-
⚛ (React Tree Reconciliation)
297+
⚛ (React Tree Reconciliation: Completed Root)
298298
⚛ A [update]
299299
⚛ B [update]
300300
@@ -308,7 +308,7 @@ exports[`ReactDebugFiberPerf skips parents during setState 1`] = `
308308
exports[`ReactDebugFiberPerf supports portals 1`] = `
309309
"⚛ (Waiting for async callback... will force flush in 5230 ms)
310310
311-
⚛ (React Tree Reconciliation)
311+
⚛ (React Tree Reconciliation: Completed Root)
312312
⚛ Parent [mount]
313313
⚛ Child [mount]
314314
@@ -322,7 +322,7 @@ exports[`ReactDebugFiberPerf supports portals 1`] = `
322322
exports[`ReactDebugFiberPerf supports returns 1`] = `
323323
"⚛ (Waiting for async callback... will force flush in 5230 ms)
324324
325-
⚛ (React Tree Reconciliation)
325+
⚛ (React Tree Reconciliation: Completed Root)
326326
⚛ App [mount]
327327
⚛ CoParent [mount]
328328
⚛ Indirection [mount]
@@ -341,18 +341,18 @@ exports[`ReactDebugFiberPerf supports returns 1`] = `
341341
exports[`ReactDebugFiberPerf warns if an in-progress update is interrupted 1`] = `
342342
"⚛ (Waiting for async callback... will force flush in 5230 ms)
343343
344-
⚛ (React Tree Reconciliation)
344+
⚛ (React Tree Reconciliation: Yielded)
345345
⚛ Foo [mount]
346346
347347
⚛ (Waiting for async callback... will force flush in 5230 ms)
348-
⛔ (React Tree Reconciliation) Warning: A top-level update interrupted the previous render
348+
⛔ (React Tree Reconciliation: Completed Root) Warning: A top-level update interrupted the previous render
349349
⚛ Foo [mount]
350350
⚛ (Committing Changes)
351351
⚛ (Committing Snapshot Effects: 0 Total)
352352
⚛ (Committing Host Effects: 1 Total)
353353
⚛ (Calling Lifecycle Methods: 0 Total)
354354
355-
⚛ (React Tree Reconciliation)
355+
⚛ (React Tree Reconciliation: Completed Root)
356356
357357
⚛ (Committing Changes)
358358
⚛ (Committing Snapshot Effects: 0 Total)
@@ -364,7 +364,7 @@ exports[`ReactDebugFiberPerf warns if an in-progress update is interrupted 1`] =
364364
exports[`ReactDebugFiberPerf warns if async work expires (starvation) 1`] = `
365365
"⛔ (Waiting for async callback... will force flush in 5230 ms) Warning: React was blocked by main thread
366366
367-
⚛ (React Tree Reconciliation)
367+
⚛ (React Tree Reconciliation: Completed Root)
368368
⚛ Foo [mount]
369369
370370
⚛ (Committing Changes)
@@ -378,7 +378,7 @@ exports[`ReactDebugFiberPerf warns on cascading renders from setState 1`] = `
378378
"⚛ (Waiting for async callback... will force flush in 5230 ms)
379379
380380
// Should print a warning
381-
⚛ (React Tree Reconciliation)
381+
⚛ (React Tree Reconciliation: Completed Root)
382382
⚛ Parent [mount]
383383
⚛ Cascading [mount]
384384
@@ -388,7 +388,7 @@ exports[`ReactDebugFiberPerf warns on cascading renders from setState 1`] = `
388388
⚛ (Calling Lifecycle Methods: 1 Total)
389389
⛔ Cascading.componentDidMount Warning: Scheduled a cascading update
390390
391-
⚛ (React Tree Reconciliation)
391+
⚛ (React Tree Reconciliation: Completed Root)
392392
⚛ Cascading [update]
393393
394394
⚛ (Committing Changes)
@@ -402,7 +402,7 @@ exports[`ReactDebugFiberPerf warns on cascading renders from top-level render 1`
402402
"⚛ (Waiting for async callback... will force flush in 5230 ms)
403403
404404
// Rendering the first root
405-
⚛ (React Tree Reconciliation)
405+
⚛ (React Tree Reconciliation: Completed Root)
406406
⚛ Cascading [mount]
407407
408408
⛔ (Committing Changes) Warning: Lifecycle hook scheduled a cascading update
@@ -412,7 +412,7 @@ exports[`ReactDebugFiberPerf warns on cascading renders from top-level render 1`
412412
⛔ Cascading.componentDidMount Warning: Scheduled a cascading update
413413
414414
// Scheduling another root from componentDidMount
415-
⚛ (React Tree Reconciliation)
415+
⚛ (React Tree Reconciliation: Completed Root)
416416
⚛ Child [mount]
417417
418418
⚛ (Committing Changes)

0 commit comments

Comments
 (0)