@@ -1066,10 +1066,7 @@ function reappearLayoutEffectsOnFiber(node: Fiber) {
1066
1066
}
1067
1067
}
1068
1068
1069
- function commitTransitionProgress (
1070
- finishedRoot : FiberRoot ,
1071
- offscreenFiber : Fiber ,
1072
- ) {
1069
+ function commitTransitionProgress ( offscreenFiber : Fiber ) {
1073
1070
if ( enableTransitionTracing ) {
1074
1071
// This function adds suspense boundaries to the root
1075
1072
// or tracing marker's pendingSuspenseBoundaries map.
@@ -1094,12 +1091,7 @@ function commitTransitionProgress(
1094
1091
const wasHidden = prevState !== null ;
1095
1092
const isHidden = nextState !== null ;
1096
1093
1097
- const rootState : RootState = finishedRoot . current . memoizedState ;
1098
- // TODO(luna) move pendingSuspenseBoundaries and transitions from
1099
- // HostRoot fiber to FiberRoot
1100
- const rootPendingBoundaries = rootState . pendingSuspenseBoundaries ;
1101
- const rootTransitions = rootState . transitions ;
1102
-
1094
+ const suspenseBoundaries = ( offscreenFiber . updateQueue : any ) . markers ;
1103
1095
// If there is a name on the suspense boundary, store that in
1104
1096
// the pending boundaries.
1105
1097
let name = null ;
@@ -1112,38 +1104,26 @@ function commitTransitionProgress(
1112
1104
name = parent . memoizedProps . unstable_name ;
1113
1105
}
1114
1106
1115
- if ( rootPendingBoundaries !== null ) {
1116
- if ( previousFiber === null ) {
1117
- // Initial mount
1118
- if ( isHidden ) {
1119
- rootPendingBoundaries . set ( offscreenInstance , {
1107
+ if ( ! wasHidden && isHidden ) {
1108
+ // The suspense boundaries was just hidden. Add the boundary
1109
+ // to the pending boundary set if it's there
1110
+ if ( suspenseBoundaries !== null ) {
1111
+ suspenseBoundaries . forEach ( pendingBoundaries => {
1112
+ pendingBoundaries . set ( offscreenInstance , {
1120
1113
name,
1121
1114
} ) ;
1122
- }
1123
- } else {
1124
- if ( wasHidden && ! isHidden ) {
1125
- // The suspense boundary went from hidden to visible. Remove
1126
- // the boundary from the pending suspense boundaries set
1127
- // if it's there
1128
- if ( rootPendingBoundaries . has ( offscreenInstance ) ) {
1129
- rootPendingBoundaries . delete ( offscreenInstance ) ;
1130
-
1131
- if ( rootPendingBoundaries . size === 0 && rootTransitions !== null ) {
1132
- rootTransitions . forEach ( transition => {
1133
- addTransitionCompleteCallbackToPendingTransition ( {
1134
- transitionName : transition . name ,
1135
- startTime : transition . startTime ,
1136
- } ) ;
1137
- } ) ;
1138
- }
1115
+ } ) ;
1116
+ }
1117
+ } else if ( wasHidden && ! isHidden ) {
1118
+ // The suspense boundary went from hidden to visible. Remove
1119
+ // the boundary from the pending suspense boundaries set
1120
+ // if it's there
1121
+ if ( suspenseBoundaries !== null ) {
1122
+ suspenseBoundaries . forEach ( pendingBoundaries => {
1123
+ if ( pendingBoundaries . has ( offscreenInstance ) ) {
1124
+ pendingBoundaries . delete ( offscreenInstance ) ;
1139
1125
}
1140
- } else if ( ! wasHidden && isHidden ) {
1141
- // The suspense boundaries was just hidden. Add the boundary
1142
- // to the pending boundary set if it's there
1143
- rootPendingBoundaries . set ( offscreenInstance , {
1144
- name,
1145
- } ) ;
1146
- }
1126
+ } ) ;
1147
1127
}
1148
1128
}
1149
1129
}
@@ -2830,45 +2810,46 @@ function commitPassiveMountOnFiber(
2830
2810
// Get the transitions that were initiatized during the render
2831
2811
// and add a start transition callback for each of them
2832
2812
const state = finishedWork . memoizedState ;
2833
- // TODO Since it's a mutable field, this should live on the FiberRoot
2834
- if ( state . transitions === null ) {
2835
- state . transitions = new Set ( [ ] ) ;
2836
- }
2837
- const pendingTransitions = state . transitions ;
2838
- const pendingSuspenseBoundaries = state . pendingSuspenseBoundaries ;
2839
-
2813
+ let incompleteTransitions = state . incompleteTransitions ;
2840
2814
// Initial render
2841
2815
if ( committedTransitions !== null ) {
2816
+ if ( state . incompleteTransitions === null ) {
2817
+ state . incompleteTransitions = incompleteTransitions = new Map ( ) ;
2818
+ }
2819
+
2842
2820
committedTransitions . forEach ( transition => {
2843
2821
addTransitionStartCallbackToPendingTransition ( {
2844
2822
transitionName : transition . name ,
2845
2823
startTime : transition . startTime ,
2846
2824
} ) ;
2847
- pendingTransitions . add ( transition ) ;
2825
+
2826
+ if ( ! incompleteTransitions . has ( transition ) ) {
2827
+ incompleteTransitions . set ( transition , null ) ;
2828
+ }
2848
2829
} ) ;
2849
2830
2850
- if (
2851
- pendingSuspenseBoundaries === null ||
2852
- pendingSuspenseBoundaries . size === 0
2853
- ) {
2854
- pendingTransitions . forEach ( transition => {
2831
+ clearTransitionsForLanes ( finishedRoot , committedLanes ) ;
2832
+ }
2833
+
2834
+ if ( incompleteTransitions !== null ) {
2835
+ incompleteTransitions . forEach ( ( pendingBoundaries , transition ) => {
2836
+ if ( pendingBoundaries === null || pendingBoundaries . size === 0 ) {
2855
2837
addTransitionCompleteCallbackToPendingTransition ( {
2856
2838
transitionName : transition . name ,
2857
2839
startTime : transition . startTime ,
2858
2840
} ) ;
2859
- } ) ;
2860
- }
2861
-
2862
- clearTransitionsForLanes ( finishedRoot , committedLanes ) ;
2841
+ incompleteTransitions . delete ( transition ) ;
2842
+ }
2843
+ } ) ;
2863
2844
}
2864
2845
2865
2846
// If there are no more pending suspense boundaries we
2866
2847
// clear the transitions because they are all complete.
2867
2848
if (
2868
- pendingSuspenseBoundaries === null ||
2869
- pendingSuspenseBoundaries . size === 0
2849
+ incompleteTransitions === null ||
2850
+ incompleteTransitions . size === 0
2870
2851
) {
2871
- state . transitions = null ;
2852
+ state . incompleteTransitions = null ;
2872
2853
}
2873
2854
}
2874
2855
break ;
@@ -2911,37 +2892,50 @@ function commitPassiveMountOnFiber(
2911
2892
const rootMemoizedState = finishedRoot . current . memoizedState ;
2912
2893
2913
2894
if ( queue !== null ) {
2914
- // We have one instance of the pendingSuspenseBoundaries map.
2915
- // We only need one because we update it during the commit phase.
2916
- // We instantiate a new Map if we haven't already
2917
- if ( rootMemoizedState . pendingSuspenseBoundaries === null ) {
2918
- rootMemoizedState . pendingSuspenseBoundaries = new Map ( ) ;
2919
- }
2920
-
2921
2895
if ( isFallback ) {
2922
2896
const transitions = queue . transitions ;
2923
2897
let prevTransitions = finishedWork . memoizedState . transitions ;
2924
- // Add all the transitions saved in the update queue during
2925
- // the render phase (ie the transitions associated with this boundary)
2926
- // into the transitions set.
2927
- if ( transitions !== null ) {
2928
- if ( prevTransitions === null ) {
2929
- // We only have one instance of the transitions set
2930
- // because we update it only during the commit phase. We
2931
- // will create the set on a as needed basis in the commit phase
2932
- finishedWork . memoizedState . transitions = prevTransitions = new Set ( ) ;
2933
- }
2898
+ let rootIncompleteTransitions =
2899
+ rootMemoizedState . incompleteTransitions ;
2900
+
2901
+ // We lazily instantiate transition tracing relevant maps
2902
+ // and sets in the commit phase as we need to use them. We only
2903
+ // instantiate them in the fallback phase on an as needed basis
2904
+ if ( rootMemoizedState . incompleteTransitions === null ) {
2905
+ rootMemoizedState . incompleteTransitions = rootIncompleteTransitions = new Map ( ) ;
2906
+ }
2907
+ if ( queue . markers === null ) {
2908
+ queue . markers = new Set ( ) ;
2909
+ }
2910
+ if ( transitions !== null && prevTransitions === null ) {
2911
+ finishedWork . memoizedState . transitions = prevTransitions = new Set ( ) ;
2912
+ }
2934
2913
2914
+ if ( transitions !== null ) {
2935
2915
transitions . forEach ( transition => {
2916
+ // Add all the transitions saved in the update queue during
2917
+ // the render phase (ie the transitions associated with this boundary)
2918
+ // into the transitions set.
2936
2919
prevTransitions . add ( transition ) ;
2920
+
2921
+ // Add the root transition's pending suspense boundary set to
2922
+ // the queue's marker set. We will iterate through the marker
2923
+ // set when we toggle state on the suspense boundary and
2924
+ // add or remove the pending suspense boundaries as needed.
2925
+ if ( ! rootIncompleteTransitions . has ( transition ) ) {
2926
+ rootIncompleteTransitions . set ( transition , new Map ( ) ) ;
2927
+ }
2928
+ queue . markers . add ( rootIncompleteTransitions . get ( transition ) ) ;
2937
2929
} ) ;
2938
2930
}
2939
2931
}
2940
- }
2941
2932
2942
- commitTransitionProgress ( finishedRoot , finishedWork ) ;
2933
+ commitTransitionProgress ( finishedWork ) ;
2943
2934
2944
- finishedWork . updateQueue = null ;
2935
+ if ( queue . markers === null || queue . markers . size === 0 ) {
2936
+ finishedWork . updateQueue = null ;
2937
+ }
2938
+ }
2945
2939
}
2946
2940
2947
2941
break ;
0 commit comments