@@ -83,6 +83,8 @@ import {
83
83
logSuspendedCommitPhase ,
84
84
logCommitPhase ,
85
85
logPaintYieldPhase ,
86
+ logStartViewTransitionYieldPhase ,
87
+ logAnimatingPhase ,
86
88
logPassiveCommitPhase ,
87
89
logYieldTime ,
88
90
logActionYieldTime ,
@@ -674,6 +676,11 @@ const IMMEDIATE_COMMIT = 0;
674
676
const SUSPENDED_COMMIT = 1 ;
675
677
const THROTTLED_COMMIT = 2 ;
676
678
679
+ type DelayedCommitReason = 0 | 1 | 2 | 3 ;
680
+ const ABORTED_VIEW_TRANSITION_COMMIT = 1 ;
681
+ const DELAYED_PASSIVE_COMMIT = 2 ;
682
+ const ANIMATION_STARTED_COMMIT = 3 ;
683
+
677
684
const NO_PENDING_EFFECTS = 0 ;
678
685
const PENDING_MUTATION_PHASE = 1 ;
679
686
const PENDING_LAYOUT_PHASE = 2 ;
@@ -696,6 +703,7 @@ let pendingViewTransitionEvents: Array<(types: Array<string>) => void> | null =
696
703
let pendingTransitionTypes : null | TransitionTypes = null ;
697
704
let pendingDidIncludeRenderPhaseUpdate : boolean = false ;
698
705
let pendingSuspendedCommitReason : SuspendedCommitReason = IMMEDIATE_COMMIT ; // Profiling-only
706
+ let pendingDelayedCommitReason : DelayedCommitReason = IMMEDIATE_COMMIT ; // Profiling-only
699
707
700
708
// Use these to prevent an infinite loop of nested updates
701
709
const NESTED_UPDATE_LIMIT = 50 ;
@@ -3436,6 +3444,7 @@ function commitRoot(
3436
3444
if ( enableProfilerTimer ) {
3437
3445
pendingEffectsRenderEndTime = completedRenderEndTime ;
3438
3446
pendingSuspendedCommitReason = suspendedCommitReason ;
3447
+ pendingDelayedCommitReason = IMMEDIATE_COMMIT ;
3439
3448
}
3440
3449
3441
3450
if ( enableGestureTransition && isGestureRender ( lanes ) ) {
@@ -3495,7 +3504,10 @@ function commitRoot(
3495
3504
// event when logging events.
3496
3505
trackSchedulerEvent ( ) ;
3497
3506
}
3498
- flushPassiveEffects ( true ) ;
3507
+ if ( pendingDelayedCommitReason === IMMEDIATE_COMMIT ) {
3508
+ pendingDelayedCommitReason = DELAYED_PASSIVE_COMMIT ;
3509
+ }
3510
+ flushPassiveEffects ( ) ;
3499
3511
// This render triggered passive effects: release the root cache pool
3500
3512
// *after* passive effects fire to avoid freeing a cache pool that may
3501
3513
// be referenced by a node in the tree (HostRoot, Cache boundary etc)
@@ -3736,6 +3748,23 @@ function flushLayoutEffects(): void {
3736
3748
ReactSharedInternals . T = prevTransition ;
3737
3749
}
3738
3750
}
3751
+
3752
+ const completedRenderEndTime = pendingEffectsRenderEndTime ;
3753
+ const suspendedCommitReason = pendingSuspendedCommitReason ;
3754
+
3755
+ if ( enableProfilerTimer && enableComponentPerformanceTrack ) {
3756
+ recordCommitEndTime ( ) ;
3757
+ logCommitPhase (
3758
+ suspendedCommitReason === IMMEDIATE_COMMIT
3759
+ ? completedRenderEndTime
3760
+ : commitStartTime ,
3761
+ commitEndTime ,
3762
+ commitErrors ,
3763
+ pendingDelayedCommitReason === ABORTED_VIEW_TRANSITION_COMMIT ,
3764
+ workInProgressUpdateTask ,
3765
+ ) ;
3766
+ }
3767
+
3739
3768
pendingEffectsStatus = PENDING_AFTER_MUTATION_PHASE ;
3740
3769
}
3741
3770
@@ -3748,6 +3777,25 @@ function flushSpawnedWork(): void {
3748
3777
) {
3749
3778
return ;
3750
3779
}
3780
+ if ( enableProfilerTimer && enableComponentPerformanceTrack ) {
3781
+ // If we didn't skip the after mutation phase, when is means we started an animation.
3782
+ const startedAnimation = pendingEffectsStatus === PENDING_SPAWNED_WORK ;
3783
+ if ( startedAnimation ) {
3784
+ const startViewTransitionStartTime = commitEndTime ;
3785
+ // Update the new commitEndTime to when we started the animation.
3786
+ recordCommitEndTime ( ) ;
3787
+ logStartViewTransitionYieldPhase (
3788
+ startViewTransitionStartTime ,
3789
+ commitEndTime ,
3790
+ pendingDelayedCommitReason === ABORTED_VIEW_TRANSITION_COMMIT ,
3791
+ workInProgressUpdateTask , // TODO: Use a ViewTransition Task.
3792
+ ) ;
3793
+ if ( pendingDelayedCommitReason !== ABORTED_VIEW_TRANSITION_COMMIT ) {
3794
+ pendingDelayedCommitReason = ANIMATION_STARTED_COMMIT ;
3795
+ }
3796
+ }
3797
+ }
3798
+
3751
3799
pendingEffectsStatus = NO_PENDING_EFFECTS ;
3752
3800
3753
3801
pendingViewTransition = null ; // The view transition has now fully started.
@@ -3759,22 +3807,8 @@ function flushSpawnedWork(): void {
3759
3807
const root = pendingEffectsRoot ;
3760
3808
const finishedWork = pendingFinishedWork ;
3761
3809
const lanes = pendingEffectsLanes ;
3762
- const completedRenderEndTime = pendingEffectsRenderEndTime ;
3763
3810
const recoverableErrors = pendingRecoverableErrors ;
3764
3811
const didIncludeRenderPhaseUpdate = pendingDidIncludeRenderPhaseUpdate ;
3765
- const suspendedCommitReason = pendingSuspendedCommitReason ;
3766
-
3767
- if ( enableProfilerTimer && enableComponentPerformanceTrack ) {
3768
- recordCommitEndTime ( ) ;
3769
- logCommitPhase (
3770
- suspendedCommitReason === IMMEDIATE_COMMIT
3771
- ? completedRenderEndTime
3772
- : commitStartTime ,
3773
- commitEndTime ,
3774
- commitErrors ,
3775
- workInProgressUpdateTask ,
3776
- ) ;
3777
- }
3778
3812
3779
3813
const passiveSubtreeMask =
3780
3814
enableViewTransition && includesOnlyViewTransitionEligibleLanes ( lanes )
@@ -4141,7 +4175,14 @@ function releaseRootPooledCache(root: FiberRoot, remainingLanes: Lanes) {
4141
4175
4142
4176
let didWarnAboutInterruptedViewTransitions = false ;
4143
4177
4144
- export function flushPendingEffects ( wasDelayedCommit ?: boolean ) : boolean {
4178
+ export function flushPendingEffectsDelayed ( ) : boolean {
4179
+ if ( pendingDelayedCommitReason === IMMEDIATE_COMMIT ) {
4180
+ pendingDelayedCommitReason = DELAYED_PASSIVE_COMMIT ;
4181
+ }
4182
+ return flushPendingEffects ( ) ;
4183
+ }
4184
+
4185
+ export function flushPendingEffects ( ) : boolean {
4145
4186
// Returns whether passive effects were flushed.
4146
4187
if ( enableViewTransition && pendingViewTransition !== null ) {
4147
4188
// If we forced a flush before the View Transition full started then we skip it.
@@ -4159,17 +4200,18 @@ export function flushPendingEffects(wasDelayedCommit?: boolean): boolean {
4159
4200
}
4160
4201
}
4161
4202
pendingViewTransition = null ;
4203
+ pendingDelayedCommitReason = ABORTED_VIEW_TRANSITION_COMMIT ;
4162
4204
}
4163
4205
flushGestureMutations ( ) ;
4164
4206
flushGestureAnimations ( ) ;
4165
4207
flushMutationEffects ( ) ;
4166
4208
flushLayoutEffects ( ) ;
4167
4209
// Skip flushAfterMutation if we're forcing this early.
4168
4210
flushSpawnedWork ( ) ;
4169
- return flushPassiveEffects ( wasDelayedCommit ) ;
4211
+ return flushPassiveEffects ( ) ;
4170
4212
}
4171
4213
4172
- function flushPassiveEffects ( wasDelayedCommit ?: boolean ) : boolean {
4214
+ function flushPassiveEffects ( ) : boolean {
4173
4215
if ( pendingEffectsStatus !== PENDING_PASSIVE_PHASE ) {
4174
4216
return false ;
4175
4217
}
@@ -4194,7 +4236,7 @@ function flushPassiveEffects(wasDelayedCommit?: boolean): boolean {
4194
4236
try {
4195
4237
setCurrentUpdatePriority ( priority ) ;
4196
4238
ReactSharedInternals . T = null ;
4197
- return flushPassiveEffectsImpl ( wasDelayedCommit ) ;
4239
+ return flushPassiveEffectsImpl ( ) ;
4198
4240
} finally {
4199
4241
setCurrentUpdatePriority ( previousPriority ) ;
4200
4242
ReactSharedInternals . T = prevTransition ;
@@ -4206,7 +4248,7 @@ function flushPassiveEffects(wasDelayedCommit?: boolean): boolean {
4206
4248
}
4207
4249
}
4208
4250
4209
- function flushPassiveEffectsImpl ( wasDelayedCommit : void | boolean ) {
4251
+ function flushPassiveEffectsImpl ( ) {
4210
4252
// Cache and clear the transitions flag
4211
4253
const transitions = pendingPassiveTransitions ;
4212
4254
pendingPassiveTransitions = null ;
@@ -4246,12 +4288,21 @@ function flushPassiveEffectsImpl(wasDelayedCommit: void | boolean) {
4246
4288
if ( enableProfilerTimer && enableComponentPerformanceTrack ) {
4247
4289
resetCommitErrors ( ) ;
4248
4290
passiveEffectStartTime = now ( ) ;
4249
- logPaintYieldPhase (
4250
- commitEndTime ,
4251
- passiveEffectStartTime ,
4252
- ! ! wasDelayedCommit ,
4253
- workInProgressUpdateTask ,
4254
- ) ;
4291
+ if ( pendingDelayedCommitReason === ANIMATION_STARTED_COMMIT ) {
4292
+ // The animation was started, so we've been animating since that happened.
4293
+ logAnimatingPhase (
4294
+ commitEndTime ,
4295
+ passiveEffectStartTime ,
4296
+ workInProgressUpdateTask , // TODO: Use a ViewTransition Task
4297
+ ) ;
4298
+ } else {
4299
+ logPaintYieldPhase (
4300
+ commitEndTime ,
4301
+ passiveEffectStartTime ,
4302
+ pendingDelayedCommitReason === DELAYED_PASSIVE_COMMIT ,
4303
+ workInProgressUpdateTask ,
4304
+ ) ;
4305
+ }
4255
4306
}
4256
4307
4257
4308
if ( enableSchedulingProfiler ) {
0 commit comments