@samitouri / QOS-React / commits / a9f14cb44e

Fix Logging of Immediately Resolved Promises (#31610)

This avoid re-emitting the yellow "Event" log when we ping inside the original event. Instead of treating events as repeated when we get repeated updates, we treat them as repeated if we've ever logged out this event before. Additionally, in the case the prerender sibling flag is on we need to ensure that if a render gets interrupted when it has been suspended we treat that as "Prewarm" instead of "Interrupted Render". Before: <img width="539" alt="Screenshot 2024-11-19 at 2 39 44 PM" src="https://github.com/user-attachments/assets/190ca50c-5168-40d8-a6fd-6b9a583af1f0"> After: <img width="1004" alt="Screenshot 2024-11-21 at 4 53 16 PM" src="https://github.com/user-attachments/assets/0c441ada-1ed1-412c-8935-aaf040c25dfe">

Sebastian Markbåge committed Nov 21, 2024 at 17:16 UTC a9f14cb44e58c13843cdeacc7dc352562cb3b976
2 files changed +33 -26
packages/react-reconciler/src/ReactFiberWorkLoop.js
+13 -4
@@ -265,7 +265,6 @@ import {
265 startProfilerTimer,
266 stopProfilerTimerIfRunningAndRecordDuration,
267 stopProfilerTimerIfRunningAndRecordIncompleteDuration,
268 - markUpdateAsRepeat,
268 trackSuspendedTime,
269 startYieldTimer,
270 yieldStartTime,
@@ -927,6 +926,7 @@ export function performWorkOnRoot(
926 // We've returned from yielding to the event loop. Let's log the time it took.
927 const yieldEndTime = now();
928 switch (yieldReason) {
929 + case SuspendedOnImmediate:
930 case SuspendedOnData:
931 logSuspendedYieldTime(yieldStartTime, yieldEndTime, yieldedFiber);
932 break;
@@ -1009,7 +1009,6 @@ export function performWorkOnRoot(
1009 setCurrentTrackFromLanes(lanes);
1010 logInconsistentRender(renderStartTime, renderEndTime);
1011 finalizeRender(lanes, renderEndTime);
1012 - markUpdateAsRepeat(lanes);
1012 }
1013 // A store was mutated in an interleaved event. Render again,
1014 // synchronously, to block further mutations.
@@ -1036,7 +1035,6 @@ export function performWorkOnRoot(
1035 setCurrentTrackFromLanes(lanes);
1036 logErroredRenderPhase(renderStartTime, renderEndTime);
1037 finalizeRender(lanes, renderEndTime);
1039 - markUpdateAsRepeat(lanes);
1038 }
1039 lanes = errorRetryLanes;
1040 exitStatus = recoverFromConcurrentError(
@@ -1740,7 +1738,18 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
1738 previousRenderStartTime > 0
1739 ) {
1740 setCurrentTrackFromLanes(workInProgressRootRenderLanes);
1743 - logInterruptedRenderPhase(previousRenderStartTime, renderStartTime);
1741 + if (
1742 + workInProgressRootExitStatus === RootSuspended ||
1743 + workInProgressRootExitStatus === RootSuspendedWithDelay
1744 + ) {
1745 + // If the root was already suspended when it got interrupted and restarted,
1746 + // then this is considered a prewarm and not an interrupted render because
1747 + // we couldn't have shown anything anyway so it's not a bad thing that we
1748 + // got interrupted.
1749 + logSuspendedRenderPhase(previousRenderStartTime, renderStartTime);
1750 + } else {
1751 + logInterruptedRenderPhase(previousRenderStartTime, renderStartTime);
1752 + }
1753 finalizeRender(workInProgressRootRenderLanes, renderStartTime);
1754 }
1755
packages/react-reconciler/src/ReactProfilerTimer.js
+20 -22
@@ -80,9 +80,12 @@ export function startUpdateTimerByLane(lane: Lane): void {
80 blockingUpdateTime = now();
81 const newEventTime = resolveEventTimeStamp();
82 const newEventType = resolveEventType();
83 - blockingEventIsRepeat =
84 - newEventTime === blockingEventTime &&
85 - newEventType === blockingEventType;
83 + if (
84 + newEventTime !== blockingEventTime ||
85 + newEventType !== blockingEventType
86 + ) {
87 + blockingEventIsRepeat = false;
88 + }
89 blockingEventTime = newEventTime;
90 blockingEventType = newEventType;
91 }
@@ -92,9 +95,12 @@ export function startUpdateTimerByLane(lane: Lane): void {
95 if (transitionStartTime < 0) {
96 const newEventTime = resolveEventTimeStamp();
97 const newEventType = resolveEventType();
95 - transitionEventIsRepeat =
96 - newEventTime === transitionEventTime &&
97 - newEventType === transitionEventType;
98 + if (
99 + newEventTime !== transitionEventTime ||
100 + newEventType !== transitionEventType
101 + ) {
102 + transitionEventIsRepeat = false;
103 + }
104 transitionEventTime = newEventTime;
105 transitionEventType = newEventType;
106 }
@@ -102,19 +108,6 @@ export function startUpdateTimerByLane(lane: Lane): void {
108 }
109 }
110
105 -export function markUpdateAsRepeat(lanes: Lanes): void {
106 - if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
107 - return;
108 - }
109 - // We're about to do a retry of this render. It is not a new update, so treat this
110 - // as a repeat within the same event.
111 - if (includesSyncLane(lanes) || includesBlockingLane(lanes)) {
112 - blockingEventIsRepeat = true;
113 - } else if (includesTransitionLane(lanes)) {
114 - transitionEventIsRepeat = true;
115 - }
116 -}
117 -
111 export function trackSuspendedTime(lanes: Lanes, renderEndTime: number) {
112 if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
113 return;
@@ -129,6 +122,7 @@ export function trackSuspendedTime(lanes: Lanes, renderEndTime: number) {
122 export function clearBlockingTimers(): void {
123 blockingUpdateTime = -1.1;
124 blockingSuspendedTime = -1.1;
125 + blockingEventIsRepeat = true;
126 }
127
128 export function startAsyncTransitionTimer(): void {
@@ -139,9 +133,12 @@ export function startAsyncTransitionTimer(): void {
133 transitionStartTime = now();
134 const newEventTime = resolveEventTimeStamp();
135 const newEventType = resolveEventType();
142 - transitionEventIsRepeat =
143 - newEventTime === transitionEventTime &&
144 - newEventType === transitionEventType;
136 + if (
137 + newEventTime !== transitionEventTime ||
138 + newEventType !== transitionEventType
139 + ) {
140 + transitionEventIsRepeat = false;
141 + }
142 transitionEventTime = newEventTime;
143 transitionEventType = newEventType;
144 }
@@ -173,6 +170,7 @@ export function clearTransitionTimers(): void {
170 transitionStartTime = -1.1;
171 transitionUpdateTime = -1.1;
172 transitionSuspendedTime = -1.1;
173 + transitionEventIsRepeat = true;
174 }
175
176 export function clampBlockingTimers(finalTime: number): void {