[Transition Tracing] Add Offscreen Queue (#24341)
Adds an Offscreen Queue. We use the offscreen queue to store not yet processed transitions. During the commit phase, we will add these transitions to the transitions field in memoizedState (in the subsequent PR) and clear the transitions field in the updateQueue
Luna Ruan committed
Apr 12, 2022 at 10:42 UTC
f7cf077cca6524877cb837adb9a8ff54242672b1
5 files changed
+79
packages/react-reconciler/src/ReactFiberBeginWork.new.js
+32
@@ -26,6 +26,7 @@ import type {SuspenseContext} from './ReactFiberSuspenseContext.new';
26
import type {
27
OffscreenProps,
28
OffscreenState,
29
+ OffscreenQueue,
30
} from './ReactFiberOffscreenComponent';
31
import type {
32
Cache,
@@ -255,6 +256,7 @@ import {
256
getSuspendedCache,
257
pushTransition,
258
getOffscreenDeferredCache,
259
+ getSuspendedTransitions,
260
} from './ReactFiberTransition.new';
261
262
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
@@ -2161,6 +2163,16 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
2163
renderLanes,
2164
);
2165
workInProgress.memoizedState = SUSPENDED_MARKER;
2166
+ if (enableTransitionTracing) {
2167
+ const currentTransitions = getSuspendedTransitions();
2168
+ if (currentTransitions !== null) {
2169
+ const primaryChildUpdateQueue: OffscreenQueue = {
2170
+ transitions: currentTransitions,
2171
+ };
2172
+ primaryChildFragment.updateQueue = primaryChildUpdateQueue;
2173
+ }
2174
+ }
2175
+
2176
return fallbackFragment;
2177
} else if (
2178
enableCPUSuspense &&
@@ -2281,6 +2293,15 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
2293
prevOffscreenState === null
2294
? mountSuspenseOffscreenState(renderLanes)
2295
: updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
2296
+ if (enableTransitionTracing) {
2297
+ const currentTransitions = getSuspendedTransitions();
2298
+ if (currentTransitions !== null) {
2299
+ const primaryChildUpdateQueue: OffscreenQueue = {
2300
+ transitions: currentTransitions,
2301
+ };
2302
+ primaryChildFragment.updateQueue = primaryChildUpdateQueue;
2303
+ }
2304
+ }
2305
primaryChildFragment.childLanes = getRemainingWorkInPrimaryTree(
2306
current,
2307
renderLanes,
@@ -2322,6 +2343,17 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
2343
current,
2344
renderLanes,
2345
);
2346
+
2347
+ if (enableTransitionTracing) {
2348
+ const currentTransitions = getSuspendedTransitions();
2349
+ if (currentTransitions !== null) {
2350
+ const primaryChildUpdateQueue: OffscreenQueue = {
2351
+ transitions: currentTransitions,
2352
+ };
2353
+ primaryChildFragment.updateQueue = primaryChildUpdateQueue;
2354
+ }
2355
+ }
2356
+
2357
// Skip the primary children, and continue working on the
2358
// fallback children.
2359
workInProgress.memoizedState = SUSPENDED_MARKER;
packages/react-reconciler/src/ReactFiberBeginWork.old.js
+32
@@ -26,6 +26,7 @@ import type {SuspenseContext} from './ReactFiberSuspenseContext.old';
26
import type {
27
OffscreenProps,
28
OffscreenState,
29
+ OffscreenQueue,
30
} from './ReactFiberOffscreenComponent';
31
import type {
32
Cache,
@@ -255,6 +256,7 @@ import {
256
getSuspendedCache,
257
pushTransition,
258
getOffscreenDeferredCache,
259
+ getSuspendedTransitions,
260
} from './ReactFiberTransition.old';
261
262
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
@@ -2161,6 +2163,16 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
2163
renderLanes,
2164
);
2165
workInProgress.memoizedState = SUSPENDED_MARKER;
2166
+ if (enableTransitionTracing) {
2167
+ const currentTransitions = getSuspendedTransitions();
2168
+ if (currentTransitions !== null) {
2169
+ const primaryChildUpdateQueue: OffscreenQueue = {
2170
+ transitions: currentTransitions,
2171
+ };
2172
+ primaryChildFragment.updateQueue = primaryChildUpdateQueue;
2173
+ }
2174
+ }
2175
+
2176
return fallbackFragment;
2177
} else if (
2178
enableCPUSuspense &&
@@ -2281,6 +2293,15 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
2293
prevOffscreenState === null
2294
? mountSuspenseOffscreenState(renderLanes)
2295
: updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
2296
+ if (enableTransitionTracing) {
2297
+ const currentTransitions = getSuspendedTransitions();
2298
+ if (currentTransitions !== null) {
2299
+ const primaryChildUpdateQueue: OffscreenQueue = {
2300
+ transitions: currentTransitions,
2301
+ };
2302
+ primaryChildFragment.updateQueue = primaryChildUpdateQueue;
2303
+ }
2304
+ }
2305
primaryChildFragment.childLanes = getRemainingWorkInPrimaryTree(
2306
current,
2307
renderLanes,
@@ -2322,6 +2343,17 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) {
2343
current,
2344
renderLanes,
2345
);
2346
+
2347
+ if (enableTransitionTracing) {
2348
+ const currentTransitions = getSuspendedTransitions();
2349
+ if (currentTransitions !== null) {
2350
+ const primaryChildUpdateQueue: OffscreenQueue = {
2351
+ transitions: currentTransitions,
2352
+ };
2353
+ primaryChildFragment.updateQueue = primaryChildUpdateQueue;
2354
+ }
2355
+ }
2356
+
2357
// Skip the primary children, and continue working on the
2358
// fallback children.
2359
workInProgress.memoizedState = SUSPENDED_MARKER;
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+5
@@ -2781,6 +2781,11 @@ function commitPassiveMountOnFiber(
2781
}
2782
}
2783
}
2784
+
2785
+ if (enableTransitionTracing) {
2786
+ // TODO: Add code to actually process the update queue
2787
+ finishedWork.updateQueue = null;
2788
+ }
2789
break;
2790
}
2791
case CacheComponent: {
packages/react-reconciler/src/ReactFiberCommitWork.old.js
+5
@@ -2781,6 +2781,11 @@ function commitPassiveMountOnFiber(
2781
}
2782
}
2783
}
2784
+
2785
+ if (enableTransitionTracing) {
2786
+ // TODO: Add code to actually process the update queue
2787
+ finishedWork.updateQueue = null;
2788
+ }
2789
break;
2790
}
2791
case CacheComponent: {
packages/react-reconciler/src/ReactFiberOffscreenComponent.js
+5
@@ -11,6 +11,7 @@ import type {ReactNodeList, OffscreenMode} from 'shared/ReactTypes';
11
import type {Lanes} from './ReactFiberLane.old';
12
import type {SpawnedCachePool} from './ReactFiberCacheComponent.new';
13
import type {Transition} from './ReactFiberTracingMarkerComponent.new';
14
+
15
export type OffscreenProps = {|
16
// TODO: Pick an API before exposing the Offscreen type. I've chosen an enum
17
// for now, since we might have multiple variants. For example, hiding the
@@ -33,4 +34,8 @@ export type OffscreenState = {|
34
transitions: Set<Transition> | null,
35
|};
36
37
+export type OffscreenQueue = {|
38
+ transitions: Array<Transition> | null,
39
+|} | null;
40
+
41
export type OffscreenInstance = {};