73
const TransitionLane13: Lane = /* */ 0b0000000000100000000000000000000;
74
const TransitionLane14: Lane = /* */ 0b0000000001000000000000000000000;
75
76
+const TransitionUpdateLanes =
77
+ TransitionLane1 |
78
+ TransitionLane2 |
79
+ TransitionLane3 |
80
+ TransitionLane4 |
81
+ TransitionLane5 |
82
+ TransitionLane6 |
83
+ TransitionLane7 |
84
+ TransitionLane8 |
85
+ TransitionLane9 |
86
+ TransitionLane10;
87
+const TransitionDeferredLanes =
88
+ TransitionLane11 | TransitionLane12 | TransitionLane13 | TransitionLane14;
89
+
90
const RetryLanes: Lanes = /* */ 0b0000011110000000000000000000000;
91
const RetryLane1: Lane = /* */ 0b0000000010000000000000000000000;
92
const RetryLane2: Lane = /* */ 0b0000000100000000000000000000000;
108
// Any lane that might schedule an update. This is used to detect infinite
109
// update loops, so it doesn't include hydration lanes or retries.
110
export const UpdateLanes: Lanes =
97
- SyncLane | InputContinuousLane | DefaultLane | TransitionLanes;
111
+ SyncLane | InputContinuousLane | DefaultLane | TransitionUpdateLanes;
112
113
export const HydrationLanes =
114
SyncHydrationLane |
169
170
export const NoTimestamp = -1;
171
158
-let nextTransitionLane: Lane = TransitionLane1;
172
+let nextTransitionUpdateLane: Lane = TransitionLane1;
173
+let nextTransitionDeferredLane: Lane = TransitionLane11;
174
let nextRetryLane: Lane = RetryLane1;
175
176
function getHighestPriorityLanes(lanes: Lanes | Lane): Lanes {
205
case TransitionLane8:
206
case TransitionLane9:
207
case TransitionLane10:
208
+ return lanes & TransitionUpdateLanes;
209
case TransitionLane11:
210
case TransitionLane12:
211
case TransitionLane13:
212
case TransitionLane14:
197
- return lanes & TransitionLanes;
213
+ return lanes & TransitionDeferredLanes;
214
case RetryLane1:
215
case RetryLane2:
216
case RetryLane3:
695
return lanes === GestureLane;
696
}
697
682
-export function claimNextTransitionLane(): Lane {
698
+export function claimNextTransitionUpdateLane(): Lane {
699
// Cycle through the lanes, assigning each new transition to the next lane.
700
// In most cases, this means every transition gets its own lane, until we
701
// run out of lanes and cycle back to the beginning.
686
- const lane = nextTransitionLane;
687
- nextTransitionLane <<= 1;
688
- if ((nextTransitionLane & TransitionLanes) === NoLanes) {
689
- nextTransitionLane = TransitionLane1;
702
+ const lane = nextTransitionUpdateLane;
703
+ nextTransitionUpdateLane <<= 1;
704
+ if ((nextTransitionUpdateLane & TransitionUpdateLanes) === NoLanes) {
705
+ nextTransitionUpdateLane = TransitionLane1;
706
+ }
707
+ return lane;
708
+}
709
+
710
+export function claimNextTransitionDeferredLane(): Lane {
711
+ const lane = nextTransitionDeferredLane;
712
+ nextTransitionDeferredLane <<= 1;
713
+ if ((nextTransitionDeferredLane & TransitionDeferredLanes) === NoLanes) {
714
+ nextTransitionDeferredLane = TransitionLane11;
715
}
716
return lane;
717
}
977
// Entangle the spawned lane with the DeferredLane bit so that we know it
978
// was the result of another render. This lets us avoid a useDeferredValue
979
// waterfall — only the first level will defer.
980
+ // TODO: Now that there is a reserved set of transition lanes that are used
981
+ // exclusively for deferred work, we should get rid of this special
982
+ // DeferredLane bit; the same information can be inferred by checking whether
983
+ // the lane is one of the TransitionDeferredLanes. The only reason this still
984
+ // exists is because we need to also do the same for OffscreenLane. That
985
+ // requires additional changes because there are more places around the
986
+ // codebase that treat OffscreenLane as a magic value; would need to check
987
+ // for a new OffscreenDeferredLane, too. Will leave this for a follow-up.
988
const spawnedLaneIndex = laneToIndex(spawnedLane);
989
root.entangledLanes |= spawnedLane;
990
root.entanglements[spawnedLaneIndex] |=