From a9f14cb44e58c13843cdeacc7dc352562cb3b976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Thu, 21 Nov 2024 17:16:54 -0500 Subject: [PATCH] Fix Logging of Immediately Resolved Promises (#31610) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: Screenshot 2024-11-19 at 2 39 44 PM After: Screenshot 2024-11-21 at 4 53 16 PM --- .../src/ReactFiberWorkLoop.js | 17 ++++++-- .../src/ReactProfilerTimer.js | 42 +++++++++---------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.js b/packages/react-reconciler/src/ReactFiberWorkLoop.js index 8c90c6df2b6dc..9b452020375df 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.js @@ -265,7 +265,6 @@ import { startProfilerTimer, stopProfilerTimerIfRunningAndRecordDuration, stopProfilerTimerIfRunningAndRecordIncompleteDuration, - markUpdateAsRepeat, trackSuspendedTime, startYieldTimer, yieldStartTime, @@ -927,6 +926,7 @@ export function performWorkOnRoot( // We've returned from yielding to the event loop. Let's log the time it took. const yieldEndTime = now(); switch (yieldReason) { + case SuspendedOnImmediate: case SuspendedOnData: logSuspendedYieldTime(yieldStartTime, yieldEndTime, yieldedFiber); break; @@ -1009,7 +1009,6 @@ export function performWorkOnRoot( setCurrentTrackFromLanes(lanes); logInconsistentRender(renderStartTime, renderEndTime); finalizeRender(lanes, renderEndTime); - markUpdateAsRepeat(lanes); } // A store was mutated in an interleaved event. Render again, // synchronously, to block further mutations. @@ -1036,7 +1035,6 @@ export function performWorkOnRoot( setCurrentTrackFromLanes(lanes); logErroredRenderPhase(renderStartTime, renderEndTime); finalizeRender(lanes, renderEndTime); - markUpdateAsRepeat(lanes); } lanes = errorRetryLanes; exitStatus = recoverFromConcurrentError( @@ -1740,7 +1738,18 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber { previousRenderStartTime > 0 ) { setCurrentTrackFromLanes(workInProgressRootRenderLanes); - logInterruptedRenderPhase(previousRenderStartTime, renderStartTime); + if ( + workInProgressRootExitStatus === RootSuspended || + workInProgressRootExitStatus === RootSuspendedWithDelay + ) { + // If the root was already suspended when it got interrupted and restarted, + // then this is considered a prewarm and not an interrupted render because + // we couldn't have shown anything anyway so it's not a bad thing that we + // got interrupted. + logSuspendedRenderPhase(previousRenderStartTime, renderStartTime); + } else { + logInterruptedRenderPhase(previousRenderStartTime, renderStartTime); + } finalizeRender(workInProgressRootRenderLanes, renderStartTime); } diff --git a/packages/react-reconciler/src/ReactProfilerTimer.js b/packages/react-reconciler/src/ReactProfilerTimer.js index fdd7b7827b4d7..2b20f45673e34 100644 --- a/packages/react-reconciler/src/ReactProfilerTimer.js +++ b/packages/react-reconciler/src/ReactProfilerTimer.js @@ -80,9 +80,12 @@ export function startUpdateTimerByLane(lane: Lane): void { blockingUpdateTime = now(); const newEventTime = resolveEventTimeStamp(); const newEventType = resolveEventType(); - blockingEventIsRepeat = - newEventTime === blockingEventTime && - newEventType === blockingEventType; + if ( + newEventTime !== blockingEventTime || + newEventType !== blockingEventType + ) { + blockingEventIsRepeat = false; + } blockingEventTime = newEventTime; blockingEventType = newEventType; } @@ -92,9 +95,12 @@ export function startUpdateTimerByLane(lane: Lane): void { if (transitionStartTime < 0) { const newEventTime = resolveEventTimeStamp(); const newEventType = resolveEventType(); - transitionEventIsRepeat = - newEventTime === transitionEventTime && - newEventType === transitionEventType; + if ( + newEventTime !== transitionEventTime || + newEventType !== transitionEventType + ) { + transitionEventIsRepeat = false; + } transitionEventTime = newEventTime; transitionEventType = newEventType; } @@ -102,19 +108,6 @@ export function startUpdateTimerByLane(lane: Lane): void { } } -export function markUpdateAsRepeat(lanes: Lanes): void { - if (!enableProfilerTimer || !enableComponentPerformanceTrack) { - return; - } - // We're about to do a retry of this render. It is not a new update, so treat this - // as a repeat within the same event. - if (includesSyncLane(lanes) || includesBlockingLane(lanes)) { - blockingEventIsRepeat = true; - } else if (includesTransitionLane(lanes)) { - transitionEventIsRepeat = true; - } -} - export function trackSuspendedTime(lanes: Lanes, renderEndTime: number) { if (!enableProfilerTimer || !enableComponentPerformanceTrack) { return; @@ -129,6 +122,7 @@ export function trackSuspendedTime(lanes: Lanes, renderEndTime: number) { export function clearBlockingTimers(): void { blockingUpdateTime = -1.1; blockingSuspendedTime = -1.1; + blockingEventIsRepeat = true; } export function startAsyncTransitionTimer(): void { @@ -139,9 +133,12 @@ export function startAsyncTransitionTimer(): void { transitionStartTime = now(); const newEventTime = resolveEventTimeStamp(); const newEventType = resolveEventType(); - transitionEventIsRepeat = - newEventTime === transitionEventTime && - newEventType === transitionEventType; + if ( + newEventTime !== transitionEventTime || + newEventType !== transitionEventType + ) { + transitionEventIsRepeat = false; + } transitionEventTime = newEventTime; transitionEventType = newEventType; } @@ -173,6 +170,7 @@ export function clearTransitionTimers(): void { transitionStartTime = -1.1; transitionUpdateTime = -1.1; transitionSuspendedTime = -1.1; + transitionEventIsRepeat = true; } export function clampBlockingTimers(finalTime: number): void {