@@ -179,6 +179,8 @@ import {
179179 includesOnlyTransitions ,
180180 includesBlockingLane ,
181181 includesTransitionLane ,
182+ includesRetryLane ,
183+ includesIdleGroupLanes ,
182184 includesExpiredLane ,
183185 getNextLanes ,
184186 getEntangledLanes ,
@@ -201,6 +203,9 @@ import {
201203 includesOnlyViewTransitionEligibleLanes ,
202204 isGestureRender ,
203205 GestureLane ,
206+ SomeTransitionLane ,
207+ SomeRetryLane ,
208+ IdleLane ,
204209} from './ReactFiberLane' ;
205210import {
206211 DiscreteEventPriority ,
@@ -292,6 +297,8 @@ import {
292297 clearTransitionTimers ,
293298 clampBlockingTimers ,
294299 clampTransitionTimers ,
300+ clampRetryTimers ,
301+ clampIdleTimers ,
295302 markNestedUpdateScheduled ,
296303 renderStartTime ,
297304 commitStartTime ,
@@ -312,6 +319,11 @@ import {
312319 resetCommitErrors ,
313320 PINGED_UPDATE ,
314321 SPAWNED_UPDATE ,
322+ startAnimating ,
323+ stopAnimating ,
324+ animatingLanes ,
325+ retryClampTime ,
326+ idleClampTime ,
315327} from './ReactProfilerTimer' ;
316328
317329// DEV stuff
@@ -1426,6 +1438,7 @@ function finishConcurrentRender(
14261438 // immediately, wait for more data to arrive.
14271439 // TODO: Combine retry throttling with Suspensey commits. Right now they
14281440 // run one after the other.
1441+ pendingEffectsLanes = lanes ;
14291442 root . timeoutHandle = scheduleTimeout (
14301443 commitRootWhenReady . bind (
14311444 null ,
@@ -1539,6 +1552,7 @@ function commitRootWhenReady(
15391552 // Not yet ready to commit. Delay the commit until the renderer notifies
15401553 // us that it's ready. This will be canceled if we start work on the
15411554 // root again.
1555+ pendingEffectsLanes = lanes ;
15421556 root . cancelPendingCommit = schedulePendingCommit (
15431557 commitRoot . bind (
15441558 null ,
@@ -1889,6 +1903,12 @@ function finalizeRender(lanes: Lanes, finalizationTime: number): void {
18891903 if ( includesTransitionLane ( lanes ) ) {
18901904 clampTransitionTimers ( finalizationTime ) ;
18911905 }
1906+ if ( includesRetryLane ( lanes ) ) {
1907+ clampRetryTimers ( finalizationTime ) ;
1908+ }
1909+ if ( includesIdleGroupLanes ( lanes ) ) {
1910+ clampIdleTimers ( finalizationTime ) ;
1911+ }
18921912 }
18931913}
18941914
@@ -1939,6 +1959,7 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
19391959 }
19401960 finalizeRender ( workInProgressRootRenderLanes , renderStartTime ) ;
19411961 }
1962+ const previousUpdateTask = workInProgressUpdateTask ;
19421963
19431964 workInProgressUpdateTask = null ;
19441965 if ( includesSyncLane ( lanes ) || includesBlockingLane ( lanes ) ) {
@@ -1951,18 +1972,30 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
19511972 blockingEventTime >= 0 && blockingEventTime < blockingClampTime
19521973 ? blockingClampTime
19531974 : blockingEventTime ;
1975+ const clampedRenderStartTime = // Clamp the suspended time to the first event/update.
1976+ clampedEventTime >= 0
1977+ ? clampedEventTime
1978+ : clampedUpdateTime >= 0
1979+ ? clampedUpdateTime
1980+ : renderStartTime ;
19541981 if ( blockingSuspendedTime >= 0 ) {
1955- setCurrentTrackFromLanes ( lanes ) ;
1982+ setCurrentTrackFromLanes ( SyncLane ) ;
19561983 logSuspendedWithDelayPhase (
19571984 blockingSuspendedTime ,
1958- // Clamp the suspended time to the first event/update.
1959- clampedEventTime >= 0
1960- ? clampedEventTime
1961- : clampedUpdateTime >= 0
1962- ? clampedUpdateTime
1963- : renderStartTime ,
1985+ clampedRenderStartTime ,
19641986 lanes ,
1965- workInProgressUpdateTask ,
1987+ previousUpdateTask ,
1988+ ) ;
1989+ } else if (
1990+ includesSyncLane ( animatingLanes ) ||
1991+ includesBlockingLane ( animatingLanes )
1992+ ) {
1993+ // If this lane is still animating, log the time from previous render finishing to now as animating.
1994+ setCurrentTrackFromLanes ( SyncLane ) ;
1995+ logAnimatingPhase (
1996+ blockingClampTime ,
1997+ clampedRenderStartTime ,
1998+ previousUpdateTask ,
19661999 ) ;
19672000 }
19682001 logBlockingStart (
@@ -1994,19 +2027,29 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
19942027 transitionEventTime >= 0 && transitionEventTime < transitionClampTime
19952028 ? transitionClampTime
19962029 : transitionEventTime ;
2030+ const clampedRenderStartTime =
2031+ // Clamp the suspended time to the first event/update.
2032+ clampedEventTime >= 0
2033+ ? clampedEventTime
2034+ : clampedUpdateTime >= 0
2035+ ? clampedUpdateTime
2036+ : renderStartTime ;
19972037 if ( transitionSuspendedTime >= 0 ) {
1998- setCurrentTrackFromLanes ( lanes ) ;
2038+ setCurrentTrackFromLanes ( SomeTransitionLane ) ;
19992039 logSuspendedWithDelayPhase (
20002040 transitionSuspendedTime ,
2001- // Clamp the suspended time to the first event/update.
2002- clampedEventTime >= 0
2003- ? clampedEventTime
2004- : clampedUpdateTime >= 0
2005- ? clampedUpdateTime
2006- : renderStartTime ,
2041+ clampedRenderStartTime ,
20072042 lanes ,
20082043 workInProgressUpdateTask ,
20092044 ) ;
2045+ } else if ( includesTransitionLane ( animatingLanes ) ) {
2046+ // If this lane is still animating, log the time from previous render finishing to now as animating.
2047+ setCurrentTrackFromLanes ( SomeTransitionLane ) ;
2048+ logAnimatingPhase (
2049+ transitionClampTime ,
2050+ clampedRenderStartTime ,
2051+ previousUpdateTask ,
2052+ ) ;
20102053 }
20112054 logTransitionStart (
20122055 clampedStartTime ,
@@ -2022,6 +2065,20 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
20222065 ) ;
20232066 clearTransitionTimers ( ) ;
20242067 }
2068+ if ( includesRetryLane ( lanes ) ) {
2069+ if ( includesRetryLane ( animatingLanes ) ) {
2070+ // If this lane is still animating, log the time from previous render finishing to now as animating.
2071+ setCurrentTrackFromLanes ( SomeRetryLane ) ;
2072+ logAnimatingPhase ( retryClampTime , renderStartTime , previousUpdateTask ) ;
2073+ }
2074+ }
2075+ if ( includesIdleGroupLanes ( lanes ) ) {
2076+ if ( includesIdleGroupLanes ( animatingLanes ) ) {
2077+ // If this lane is still animating, log the time from previous render finishing to now as animating.
2078+ setCurrentTrackFromLanes ( IdleLane ) ;
2079+ logAnimatingPhase ( idleClampTime , renderStartTime , previousUpdateTask ) ;
2080+ }
2081+ }
20252082 }
20262083
20272084 const timeoutHandle = root . timeoutHandle ;
@@ -2038,6 +2095,8 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
20382095 cancelPendingCommit ( ) ;
20392096 }
20402097
2098+ pendingEffectsLanes = NoLanes ;
2099+
20412100 resetWorkInProgressStack ( ) ;
20422101 workInProgressRoot = root ;
20432102 const rootWorkInProgress = createWorkInProgress ( root . current , null ) ;
@@ -3592,6 +3651,9 @@ function commitRoot(
35923651
35933652 pendingEffectsStatus = PENDING_MUTATION_PHASE ;
35943653 if ( enableViewTransition && willStartViewTransition ) {
3654+ if ( enableProfilerTimer && enableComponentPerformanceTrack ) {
3655+ startAnimating ( lanes ) ;
3656+ }
35953657 pendingViewTransition = startViewTransition (
35963658 suspendedState ,
35973659 root . containerInfo ,
@@ -3603,6 +3665,15 @@ function commitRoot(
36033665 flushPassiveEffects ,
36043666 reportViewTransitionError ,
36053667 enableProfilerTimer ? suspendedViewTransition : ( null : any ) ,
3668+ enableProfilerTimer
3669+ ? // This callback fires after "pendingEffects" so we need to snapshot the arguments.
3670+ finishedViewTransition . bind (
3671+ null ,
3672+ lanes ,
3673+ // TODO: Use a ViewTransition Task
3674+ __DEV__ ? workInProgressUpdateTask : null ,
3675+ )
3676+ : ( null : any ) ,
36063677 ) ;
36073678 } else {
36083679 // Flush synchronously.
@@ -3634,13 +3705,62 @@ function suspendedViewTransition(reason: string): void {
36343705 commitEndTime ,
36353706 commitErrors ,
36363707 pendingDelayedCommitReason === ABORTED_VIEW_TRANSITION_COMMIT ,
3637- workInProgressUpdateTask ,
3708+ workInProgressUpdateTask , // TODO: Use a ViewTransition Task and this is not safe to read in this phase.
36383709 ) ;
36393710 pendingSuspendedViewTransitionReason = reason ;
36403711 pendingSuspendedCommitReason = reason ;
36413712 }
36423713}
36433714
3715+ function finishedViewTransition (
3716+ lanes : Lanes ,
3717+ task : null | ConsoleTask , // DEV-only
3718+ ) : void {
3719+ if ( enableProfilerTimer && enableComponentPerformanceTrack ) {
3720+ if ( ( animatingLanes & lanes ) === NoLanes ) {
3721+ // Was already stopped by some other action or maybe other root.
3722+ return ;
3723+ }
3724+ stopAnimating ( lanes ) ;
3725+ // If an affected track isn't in the middle of rendering or committing, log from the previous
3726+ // finished render until the end of the animation.
3727+ if (
3728+ ( includesSyncLane ( lanes ) || includesBlockingLane ( lanes ) ) &&
3729+ ! includesSyncLane ( workInProgressRootRenderLanes ) &&
3730+ ! includesBlockingLane ( workInProgressRootRenderLanes ) &&
3731+ ! includesSyncLane ( pendingEffectsLanes ) &&
3732+ ! includesBlockingLane ( pendingEffectsLanes )
3733+ ) {
3734+ setCurrentTrackFromLanes ( SyncLane ) ;
3735+ logAnimatingPhase ( blockingClampTime , now ( ) , task ) ;
3736+ }
3737+ if (
3738+ includesTransitionLane ( lanes ) &&
3739+ ! includesTransitionLane ( workInProgressRootRenderLanes ) &&
3740+ ! includesTransitionLane ( pendingEffectsLanes )
3741+ ) {
3742+ setCurrentTrackFromLanes ( SomeTransitionLane ) ;
3743+ logAnimatingPhase ( transitionClampTime , now ( ) , task ) ;
3744+ }
3745+ if (
3746+ includesRetryLane ( lanes ) &&
3747+ ! includesRetryLane ( workInProgressRootRenderLanes ) &&
3748+ ! includesRetryLane ( pendingEffectsLanes )
3749+ ) {
3750+ setCurrentTrackFromLanes ( SomeRetryLane ) ;
3751+ logAnimatingPhase ( retryClampTime , now ( ) , task ) ;
3752+ }
3753+ if (
3754+ includesIdleGroupLanes ( lanes ) &&
3755+ ! includesIdleGroupLanes ( workInProgressRootRenderLanes ) &&
3756+ ! includesIdleGroupLanes ( pendingEffectsLanes )
3757+ ) {
3758+ setCurrentTrackFromLanes ( IdleLane ) ;
3759+ logAnimatingPhase ( idleClampTime , now ( ) , task ) ;
3760+ }
3761+ }
3762+ }
3763+
36443764function flushAfterMutationEffects ( ) : void {
36453765 if ( pendingEffectsStatus !== PENDING_AFTER_MUTATION_PHASE ) {
36463766 return ;
@@ -3715,7 +3835,7 @@ function flushLayoutEffects(): void {
37153835 commitEndTime , // The start is the end of the first commit part.
37163836 commitStartTime , // The end is the start of the second commit part.
37173837 suspendedViewTransitionReason ,
3718- workInProgressUpdateTask ,
3838+ workInProgressUpdateTask , // TODO: Use a ViewTransition Task and this is not safe to read in this phase.
37193839 ) ;
37203840 }
37213841 }
0 commit comments