@samitouri / QOS-React / commits / 8dfbd16fce

[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;