Skip to content

Commit 2c6122b

Browse files
committed
Highlight hydration and offscreen render phases
1 parent d5e8f79 commit 2c6122b

File tree

3 files changed

+94
-17
lines changed

3 files changed

+94
-17
lines changed

packages/react-reconciler/src/ReactFiberLane.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,18 @@ export function includesTransitionLane(lanes: Lanes): boolean {
621621
return (lanes & TransitionLanes) !== NoLanes;
622622
}
623623

624+
export function includesOnlyHydrationLanes(lanes: Lanes): boolean {
625+
return (lanes & HydrationLanes) === lanes;
626+
}
627+
628+
export function includesOnlyOffscreenLanes(lanes: Lanes): boolean {
629+
return (lanes & OffscreenLane) === lanes;
630+
}
631+
632+
export function includesOnlyHydrationOrOffscreenLanes(lanes: Lanes): boolean {
633+
return (lanes & (HydrationLanes | OffscreenLane)) === lanes;
634+
}
635+
624636
export function includesBlockingLane(lanes: Lanes): boolean {
625637
const SyncDefaultLanes =
626638
InputContinuousHydrationLane |

packages/react-reconciler/src/ReactFiberPerformanceTrack.js

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@
99

1010
import type {Fiber} from './ReactInternalTypes';
1111

12+
import type {Lanes} from './ReactFiberLane';
13+
1214
import getComponentNameFromFiber from './getComponentNameFromFiber';
1315

14-
import {getGroupNameOfHighestPriorityLane} from './ReactFiberLane';
16+
import {
17+
getGroupNameOfHighestPriorityLane,
18+
includesOnlyHydrationLanes,
19+
includesOnlyOffscreenLanes,
20+
includesOnlyHydrationOrOffscreenLanes,
21+
} from './ReactFiberLane';
1522

1623
import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
1724

@@ -51,7 +58,7 @@ const reusableLaneOptions = {
5158
},
5259
};
5360

54-
export function setCurrentTrackFromLanes(lanes: number): void {
61+
export function setCurrentTrackFromLanes(lanes: Lanes): void {
5562
reusableLaneDevToolDetails.track = getGroupNameOfHighestPriorityLane(lanes);
5663
}
5764

@@ -223,6 +230,7 @@ export function logBlockingStart(
223230
eventType: null | string,
224231
eventIsRepeat: boolean,
225232
renderStartTime: number,
233+
lanes: Lanes,
226234
): void {
227235
if (supportsUserTiming) {
228236
reusableLaneDevToolDetails.track = 'Blocking';
@@ -240,7 +248,11 @@ export function logBlockingStart(
240248
}
241249
if (updateTime > 0) {
242250
// Log the time from when we called setState until we started rendering.
243-
reusableLaneDevToolDetails.color = 'primary-light';
251+
reusableLaneDevToolDetails.color = includesOnlyHydrationOrOffscreenLanes(
252+
lanes,
253+
)
254+
? 'tertiary-light'
255+
: 'primary-light';
244256
reusableLaneOptions.start = updateTime;
245257
reusableLaneOptions.end = renderStartTime;
246258
performance.measure('Blocked', reusableLaneOptions);
@@ -292,33 +304,65 @@ export function logTransitionStart(
292304
}
293305
}
294306

295-
export function logRenderPhase(startTime: number, endTime: number): void {
307+
export function logRenderPhase(
308+
startTime: number,
309+
endTime: number,
310+
lanes: Lanes,
311+
): void {
296312
if (supportsUserTiming) {
297-
reusableLaneDevToolDetails.color = 'primary-dark';
313+
reusableLaneDevToolDetails.color = includesOnlyHydrationOrOffscreenLanes(
314+
lanes,
315+
)
316+
? 'tertiary-dark'
317+
: 'primary-dark';
298318
reusableLaneOptions.start = startTime;
299319
reusableLaneOptions.end = endTime;
300-
performance.measure('Render', reusableLaneOptions);
320+
performance.measure(
321+
includesOnlyOffscreenLanes(lanes)
322+
? 'Prepared'
323+
: includesOnlyHydrationLanes(lanes)
324+
? 'Hydrated'
325+
: 'Render',
326+
reusableLaneOptions,
327+
);
301328
}
302329
}
303330

304331
export function logInterruptedRenderPhase(
305332
startTime: number,
306333
endTime: number,
334+
lanes: Lanes,
307335
): void {
308336
if (supportsUserTiming) {
309-
reusableLaneDevToolDetails.color = 'primary-dark';
337+
reusableLaneDevToolDetails.color = includesOnlyHydrationOrOffscreenLanes(
338+
lanes,
339+
)
340+
? 'tertiary-dark'
341+
: 'primary-dark';
310342
reusableLaneOptions.start = startTime;
311343
reusableLaneOptions.end = endTime;
312-
performance.measure('Interrupted Render', reusableLaneOptions);
344+
performance.measure(
345+
includesOnlyOffscreenLanes(lanes)
346+
? 'Prewarm'
347+
: includesOnlyHydrationLanes(lanes)
348+
? 'Interrupted Hydration'
349+
: 'Interrupted Render',
350+
reusableLaneOptions,
351+
);
313352
}
314353
}
315354

316355
export function logSuspendedRenderPhase(
317356
startTime: number,
318357
endTime: number,
358+
lanes: Lanes,
319359
): void {
320360
if (supportsUserTiming) {
321-
reusableLaneDevToolDetails.color = 'primary-dark';
361+
reusableLaneDevToolDetails.color = includesOnlyHydrationOrOffscreenLanes(
362+
lanes,
363+
)
364+
? 'tertiary-dark'
365+
: 'primary-dark';
322366
reusableLaneOptions.start = startTime;
323367
reusableLaneOptions.end = endTime;
324368
performance.measure('Prewarm', reusableLaneOptions);
@@ -328,10 +372,15 @@ export function logSuspendedRenderPhase(
328372
export function logSuspendedWithDelayPhase(
329373
startTime: number,
330374
endTime: number,
375+
lanes: Lanes,
331376
): void {
332377
// This means the render was suspended and cannot commit until it gets unblocked.
333378
if (supportsUserTiming) {
334-
reusableLaneDevToolDetails.color = 'primary-dark';
379+
reusableLaneDevToolDetails.color = includesOnlyHydrationOrOffscreenLanes(
380+
lanes,
381+
)
382+
? 'tertiary-dark'
383+
: 'primary-dark';
335384
reusableLaneOptions.start = startTime;
336385
reusableLaneOptions.end = endTime;
337386
performance.measure('Suspended', reusableLaneOptions);
@@ -341,6 +390,7 @@ export function logSuspendedWithDelayPhase(
341390
export function logErroredRenderPhase(
342391
startTime: number,
343392
endTime: number,
393+
lanes: Lanes,
344394
): void {
345395
if (supportsUserTiming) {
346396
reusableLaneDevToolDetails.color = 'error';

packages/react-reconciler/src/ReactFiberWorkLoop.js

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ export function performWorkOnRoot(
10351035
if (errorRetryLanes !== NoLanes) {
10361036
if (enableProfilerTimer && enableComponentPerformanceTrack) {
10371037
setCurrentTrackFromLanes(lanes);
1038-
logErroredRenderPhase(renderStartTime, renderEndTime);
1038+
logErroredRenderPhase(renderStartTime, renderEndTime, lanes);
10391039
finalizeRender(lanes, renderEndTime);
10401040
}
10411041
lanes = errorRetryLanes;
@@ -1066,7 +1066,7 @@ export function performWorkOnRoot(
10661066
if (exitStatus === RootFatalErrored) {
10671067
if (enableProfilerTimer && enableComponentPerformanceTrack) {
10681068
setCurrentTrackFromLanes(lanes);
1069-
logErroredRenderPhase(renderStartTime, renderEndTime);
1069+
logErroredRenderPhase(renderStartTime, renderEndTime, lanes);
10701070
finalizeRender(lanes, renderEndTime);
10711071
}
10721072
prepareFreshStack(root, NoLanes);
@@ -1207,7 +1207,7 @@ function finishConcurrentRender(
12071207
// until we receive more data.
12081208
if (enableProfilerTimer && enableComponentPerformanceTrack) {
12091209
setCurrentTrackFromLanes(lanes);
1210-
logSuspendedRenderPhase(renderStartTime, renderEndTime);
1210+
logSuspendedRenderPhase(renderStartTime, renderEndTime, lanes);
12111211
finalizeRender(lanes, renderEndTime);
12121212
trackSuspendedTime(lanes, renderEndTime);
12131213
}
@@ -1757,9 +1757,17 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
17571757
// then this is considered a prewarm and not an interrupted render because
17581758
// we couldn't have shown anything anyway so it's not a bad thing that we
17591759
// got interrupted.
1760-
logSuspendedRenderPhase(previousRenderStartTime, renderStartTime);
1760+
logSuspendedRenderPhase(
1761+
previousRenderStartTime,
1762+
renderStartTime,
1763+
lanes,
1764+
);
17611765
} else {
1762-
logInterruptedRenderPhase(previousRenderStartTime, renderStartTime);
1766+
logInterruptedRenderPhase(
1767+
previousRenderStartTime,
1768+
renderStartTime,
1769+
lanes,
1770+
);
17631771
}
17641772
finalizeRender(workInProgressRootRenderLanes, renderStartTime);
17651773
}
@@ -1783,6 +1791,7 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
17831791
: clampedUpdateTime >= 0
17841792
? clampedUpdateTime
17851793
: renderStartTime,
1794+
lanes,
17861795
);
17871796
}
17881797
logBlockingStart(
@@ -1791,6 +1800,7 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
17911800
blockingEventType,
17921801
blockingEventIsRepeat,
17931802
renderStartTime,
1803+
lanes,
17941804
);
17951805
clearBlockingTimers();
17961806
}
@@ -1817,6 +1827,7 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
18171827
: clampedUpdateTime >= 0
18181828
? clampedUpdateTime
18191829
: renderStartTime,
1830+
lanes,
18201831
);
18211832
}
18221833
logTransitionStart(
@@ -3202,9 +3213,13 @@ function commitRootImpl(
32023213
// Log the previous render phase once we commit. I.e. we weren't interrupted.
32033214
setCurrentTrackFromLanes(lanes);
32043215
if (exitStatus === RootErrored) {
3205-
logErroredRenderPhase(completedRenderStartTime, completedRenderEndTime);
3216+
logErroredRenderPhase(
3217+
completedRenderStartTime,
3218+
completedRenderEndTime,
3219+
lanes,
3220+
);
32063221
} else {
3207-
logRenderPhase(completedRenderStartTime, completedRenderEndTime);
3222+
logRenderPhase(completedRenderStartTime, completedRenderEndTime, lanes);
32083223
}
32093224
}
32103225

0 commit comments

Comments
 (0)