[Fiber] Color Performance Track Entries by Self Time (#30984)
Stacked on #30983. This colors each component entry by its self time from light to dark depending on how long it took. If it took longer than a cut off we color it red (the error color). <img width="435" alt="Screenshot 2024-09-16 at 11 48 15 PM" src="https://github.com/user-attachments/assets/5d0bda83-6205-40e9-bec1-b81db2d48b2d">
Sebastian Markbåge committed
Sep 17, 2024 at 16:36 UTC
8dfbd16fce9077ab4e5fe85a7b86fa7c97a5ae04
3 files changed
+36
-20
packages/react-reconciler/src/ReactFiberCommitWork.js
+5
@@ -109,6 +109,7 @@ import {
109
popComponentEffectStart,
110
componentEffectStartTime,
111
componentEffectEndTime,
112
+ componentEffectDuration,
113
} from './ReactProfilerTimer';
114
import {
115
logComponentRender,
@@ -608,6 +609,7 @@ function commitLayoutEffectOnFiber(
609
finishedWork,
610
componentEffectStartTime,
611
componentEffectEndTime,
612
+ componentEffectDuration,
613
);
614
}
615
@@ -2105,6 +2107,7 @@ function commitMutationEffectsOnFiber(
2107
finishedWork,
2108
componentEffectStartTime,
2109
componentEffectEndTime,
2110
+ componentEffectDuration,
2111
);
2112
}
2113
@@ -2926,6 +2929,7 @@ function commitPassiveMountOnFiber(
2929
finishedWork,
2930
componentEffectStartTime,
2931
componentEffectEndTime,
2932
+ componentEffectDuration,
2933
);
2934
}
2935
@@ -3444,6 +3448,7 @@ function commitPassiveUnmountOnFiber(finishedWork: Fiber): void {
3448
finishedWork,
3449
componentEffectStartTime,
3450
componentEffectEndTime,
3451
+ componentEffectDuration,
3452
);
3453
}
3454
packages/react-reconciler/src/ReactFiberPerformanceTrack.js
+28
-20
@@ -38,24 +38,9 @@ const reusableComponentOptions = {
38
},
39
};
40
41
-const reusableComponentEffectDevToolDetails = {
42
- dataType: 'track-entry',
43
- color: 'secondary',
44
- track: 'Blocking', // Lane
45
- trackGroup: TRACK_GROUP,
46
-};
47
-const reusableComponentEffectOptions = {
48
- start: -0,
49
- end: -0,
50
- detail: {
51
- devtools: reusableComponentEffectDevToolDetails,
52
- },
53
-};
54
-
41
export function setCurrentTrackFromLanes(lanes: number): void {
56
- reusableComponentEffectDevToolDetails.track =
57
- reusableComponentDevToolDetails.track =
58
- getGroupNameOfHighestPriorityLane(lanes);
42
+ reusableComponentDevToolDetails.track =
43
+ getGroupNameOfHighestPriorityLane(lanes);
44
}
45
46
export function logComponentRender(
@@ -69,6 +54,20 @@ export function logComponentRender(
54
return;
55
}
56
if (supportsUserTiming) {
57
+ let selfTime: number = (fiber.actualDuration: any);
58
+ if (fiber.alternate === null || fiber.alternate.child !== fiber.child) {
59
+ for (let child = fiber.child; child !== null; child = child.sibling) {
60
+ selfTime -= (child.actualDuration: any);
61
+ }
62
+ }
63
+ reusableComponentDevToolDetails.color =
64
+ selfTime < 0.5
65
+ ? 'primary-light'
66
+ : selfTime < 10
67
+ ? 'primary'
68
+ : selfTime < 100
69
+ ? 'primary-dark'
70
+ : 'error';
71
reusableComponentOptions.start = startTime;
72
reusableComponentOptions.end = endTime;
73
performance.measure(name, reusableComponentOptions);
@@ -79,6 +78,7 @@ export function logComponentEffect(
78
fiber: Fiber,
79
startTime: number,
80
endTime: number,
81
+ selfTime: number,
82
): void {
83
const name = getComponentNameFromFiber(fiber);
84
if (name === null) {
@@ -86,8 +86,16 @@ export function logComponentEffect(
86
return;
87
}
88
if (supportsUserTiming) {
89
- reusableComponentEffectOptions.start = startTime;
90
- reusableComponentEffectOptions.end = endTime;
91
- performance.measure(name, reusableComponentEffectOptions);
89
+ reusableComponentDevToolDetails.color =
90
+ selfTime < 1
91
+ ? 'secondary-light'
92
+ : selfTime < 100
93
+ ? 'secondary'
94
+ : selfTime < 500
95
+ ? 'secondary-dark'
96
+ : 'error';
97
+ reusableComponentOptions.start = startTime;
98
+ reusableComponentOptions.end = endTime;
99
+ performance.measure(name, reusableComponentOptions);
100
}
101
}
packages/react-reconciler/src/ReactProfilerTimer.js
+3
@@ -25,6 +25,7 @@ export let completeTime: number = -0;
25
export let commitTime: number = -0;
26
export let profilerStartTime: number = -1.1;
27
export let profilerEffectDuration: number = -0;
28
+export let componentEffectDuration: number = -0;
29
export let componentEffectStartTime: number = -1.1;
30
export let componentEffectEndTime: number = -1.1;
31
@@ -72,6 +73,7 @@ export function pushComponentEffectStart(): number {
73
}
74
const prevEffectStart = componentEffectStartTime;
75
componentEffectStartTime = -1.1; // Track the next start.
76
+ componentEffectDuration = -0; // Reset component level duration.
77
return prevEffectStart;
78
}
79
@@ -211,6 +213,7 @@ export function recordEffectDuration(fiber: Fiber): void {
213
// Store duration on the next nearest Profiler ancestor
214
// Or the root (for the DevTools Profiler to read)
215
profilerEffectDuration += elapsedTime;
216
+ componentEffectDuration += elapsedTime;
217
218
// Keep track of the last end time of the effects.
219
componentEffectEndTime = endTime;