Skip to content

Commit 7baf9d4

Browse files
authored
Combine Flags and SubtreeFlags types (#19775)
Because the `subtreeFlags` is the union of all the flags present in a subtree, we can use the same type as `flags`. One practical benefit is that we can bubble up the flags from the children with a single `|=` operator. Structurally, everything else about the effect algorithm is unchanged.
1 parent 1665443 commit 7baf9d4

6 files changed

+38
-113
lines changed

packages/react-reconciler/src/ReactFiber.new.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import {
3030
enableBlocksAPI,
3131
} from 'shared/ReactFeatureFlags';
3232
import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
33-
import {NoFlags as NoSubtreeEffect} from './ReactSubtreeFlags';
3433
import {ConcurrentRoot, BlockingRoot} from './ReactRootTags';
3534
import {
3635
IndeterminateComponent,
@@ -145,7 +144,7 @@ function FiberNode(
145144

146145
// Effects
147146
this.flags = NoFlags;
148-
this.subtreeFlags = NoSubtreeEffect;
147+
this.subtreeFlags = NoFlags;
149148
this.deletions = null;
150149

151150
this.lanes = NoLanes;
@@ -284,7 +283,7 @@ export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber {
284283
workInProgress.type = current.type;
285284

286285
// We already have an alternate.
287-
workInProgress.subtreeFlags = NoSubtreeEffect;
286+
workInProgress.subtreeFlags = NoFlags;
288287
workInProgress.deletions = null;
289288

290289
if (enableProfilerTimer) {
@@ -372,7 +371,7 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) {
372371
workInProgress.lanes = renderLanes;
373372

374373
workInProgress.child = null;
375-
workInProgress.subtreeFlags = NoSubtreeEffect;
374+
workInProgress.subtreeFlags = NoFlags;
376375
workInProgress.memoizedProps = null;
377376
workInProgress.memoizedState = null;
378377
workInProgress.updateQueue = null;

packages/react-reconciler/src/ReactFiberCommitWork.new.js

+2-8
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import {
7171
Placement,
7272
Snapshot,
7373
Update,
74+
PassiveMask,
7475
} from './ReactFiberFlags';
7576
import getComponentName from 'shared/getComponentName';
7677
import invariant from 'shared/invariant';
@@ -130,10 +131,6 @@ import {
130131
Passive as HookPassive,
131132
} from './ReactHookEffectTags';
132133
import {didWarnAboutReassigningProps} from './ReactFiberBeginWork.new';
133-
import {
134-
NoFlags as NoSubtreeFlags,
135-
Passive as PassiveSubtreeFlags,
136-
} from './ReactSubtreeFlags';
137134

138135
let didWarnAboutUndefinedSnapshotBeforeUpdate: Set<mixed> | null = null;
139136
if (__DEV__) {
@@ -595,10 +592,7 @@ function commitLifeCycles(
595592
commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);
596593
}
597594

598-
if (
599-
(finishedWork.subtreeFlags & PassiveSubtreeFlags) !==
600-
NoSubtreeFlags
601-
) {
595+
if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags) {
602596
schedulePassiveEffectCallback();
603597
}
604598
return;

packages/react-reconciler/src/ReactFiberCompleteWork.new.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ import {
6767
Snapshot,
6868
MutationMask,
6969
} from './ReactFiberFlags';
70-
import {NoFlags as NoSubtreeFlags, Mutation} from './ReactSubtreeFlags';
7170
import invariant from 'shared/invariant';
7271

7372
import {
@@ -166,7 +165,7 @@ function hadNoMutationsEffects(current: null | Fiber, completedWork: Fiber) {
166165
if ((child.flags & MutationMask) !== NoFlags) {
167166
return false;
168167
}
169-
if ((child.subtreeFlags & Mutation) !== NoSubtreeFlags) {
168+
if ((child.subtreeFlags & MutationMask) !== NoFlags) {
170169
return false;
171170
}
172171
child = child.sibling;

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

+31-79
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,8 @@ import {
139139
MutationMask,
140140
LayoutMask,
141141
PassiveMask,
142+
StaticMask,
142143
} from './ReactFiberFlags';
143-
import {
144-
NoFlags as NoSubtreeFlags,
145-
BeforeMutation as BeforeMutationSubtreeFlags,
146-
Mutation as MutationSubtreeFlags,
147-
Layout as LayoutSubtreeFlags,
148-
Passive as PassiveSubtreeFlags,
149-
PassiveStatic as PassiveStaticSubtreeFlags,
150-
} from './ReactSubtreeFlags';
151144
import {
152145
NoLanePriority,
153146
SyncLanePriority,
@@ -1766,7 +1759,7 @@ function completeUnitOfWork(unitOfWork: Fiber): void {
17661759
if (returnFiber !== null) {
17671760
// Mark the parent fiber as incomplete
17681761
returnFiber.flags |= Incomplete;
1769-
returnFiber.subtreeFlags = NoSubtreeFlags;
1762+
returnFiber.subtreeFlags = NoFlags;
17701763
returnFiber.deletions = null;
17711764
}
17721765
}
@@ -1809,7 +1802,7 @@ function resetChildLanes(completedWork: Fiber) {
18091802
completedWork.alternate.child === completedWork.child;
18101803

18111804
let newChildLanes = NoLanes;
1812-
let subtreeFlags = NoSubtreeFlags;
1805+
let subtreeFlags = NoFlags;
18131806

18141807
if (!didBailout) {
18151808
// Bubble up the earliest expiration time.
@@ -1827,23 +1820,7 @@ function resetChildLanes(completedWork: Fiber) {
18271820
);
18281821

18291822
subtreeFlags |= child.subtreeFlags;
1830-
1831-
const flags = child.flags;
1832-
if ((flags & BeforeMutationMask) !== NoFlags) {
1833-
subtreeFlags |= BeforeMutationSubtreeFlags;
1834-
}
1835-
if ((flags & MutationMask) !== NoFlags) {
1836-
subtreeFlags |= MutationSubtreeFlags;
1837-
}
1838-
if ((flags & LayoutMask) !== NoFlags) {
1839-
subtreeFlags |= LayoutSubtreeFlags;
1840-
}
1841-
if ((flags & PassiveMask) !== NoFlags) {
1842-
subtreeFlags |= PassiveSubtreeFlags;
1843-
}
1844-
if ((flags & PassiveStatic) !== NoFlags) {
1845-
subtreeFlags |= PassiveStaticSubtreeFlags;
1846-
}
1823+
subtreeFlags |= child.flags;
18471824

18481825
// When a fiber is cloned, its actualDuration is reset to 0. This value will
18491826
// only be updated if work is done on the fiber (i.e. it doesn't bailout).
@@ -1880,23 +1857,7 @@ function resetChildLanes(completedWork: Fiber) {
18801857
);
18811858

18821859
subtreeFlags |= child.subtreeFlags;
1883-
1884-
const flags = child.flags;
1885-
if ((flags & BeforeMutationMask) !== NoFlags) {
1886-
subtreeFlags |= BeforeMutationSubtreeFlags;
1887-
}
1888-
if ((flags & MutationMask) !== NoFlags) {
1889-
subtreeFlags |= MutationSubtreeFlags;
1890-
}
1891-
if ((flags & LayoutMask) !== NoFlags) {
1892-
subtreeFlags |= LayoutSubtreeFlags;
1893-
}
1894-
if ((flags & PassiveMask) !== NoFlags) {
1895-
subtreeFlags |= PassiveSubtreeFlags;
1896-
}
1897-
if ((flags & PassiveStatic) !== NoFlags) {
1898-
subtreeFlags |= PassiveStaticSubtreeFlags;
1899-
}
1860+
subtreeFlags |= child.flags;
19001861

19011862
child = child.sibling;
19021863
}
@@ -1917,13 +1878,12 @@ function resetChildLanes(completedWork: Fiber) {
19171878
mergeLanes(child.lanes, child.childLanes),
19181879
);
19191880

1920-
// Preserve passive static flag even in the case of a bailout;
1921-
// otherwise a subsequent unmount may bailout before calling destroy functions.
1922-
subtreeFlags |= child.subtreeFlags & PassiveStaticSubtreeFlags;
1923-
const flags = child.flags;
1924-
if ((flags & PassiveStatic) !== NoFlags) {
1925-
subtreeFlags |= PassiveStaticSubtreeFlags;
1926-
}
1881+
// "Static" flags share the lifetime of the fiber/hook they belong to,
1882+
// so we should bubble those up even during a bailout. All the other
1883+
// flags have a lifetime only of a single render + commit, so we should
1884+
// ignore them.
1885+
subtreeFlags |= child.subtreeFlags & StaticMask;
1886+
subtreeFlags |= child.flags & StaticMask;
19271887

19281888
treeBaseDuration += child.treeBaseDuration;
19291889
child = child.sibling;
@@ -1949,13 +1909,12 @@ function resetChildLanes(completedWork: Fiber) {
19491909
mergeLanes(child.lanes, child.childLanes),
19501910
);
19511911

1952-
// Preserve passive static flag even in the case of a bailout;
1953-
// otherwise a subsequent unmount may bailout before calling destroy functions.
1954-
subtreeFlags |= child.subtreeFlags & PassiveStaticSubtreeFlags;
1955-
const flags = child.flags;
1956-
if ((flags & PassiveStatic) !== NoFlags) {
1957-
subtreeFlags |= PassiveStaticSubtreeFlags;
1958-
}
1912+
// "Static" flags share the lifetime of the fiber/hook they belong to,
1913+
// so we should bubble those up even during a bailout. All the other
1914+
// flags have a lifetime only of a single render + commit, so we should
1915+
// ignore them.
1916+
subtreeFlags |= child.subtreeFlags & StaticMask;
1917+
subtreeFlags |= child.flags & StaticMask;
19591918

19601919
child = child.sibling;
19611920
}
@@ -2067,11 +2026,8 @@ function commitRootImpl(root, renderPriorityLevel) {
20672026
// Reconsider whether this is necessary.
20682027
const subtreeHasEffects =
20692028
(finishedWork.subtreeFlags &
2070-
(BeforeMutationSubtreeFlags |
2071-
MutationSubtreeFlags |
2072-
LayoutSubtreeFlags |
2073-
PassiveSubtreeFlags)) !==
2074-
NoSubtreeFlags;
2029+
(BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !==
2030+
NoFlags;
20752031
const rootHasEffect =
20762032
(finishedWork.flags &
20772033
(BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !==
@@ -2152,7 +2108,7 @@ function commitRootImpl(root, renderPriorityLevel) {
21522108

21532109
// If there are pending passive effects, schedule a callback to process them.
21542110
if (
2155-
(finishedWork.subtreeFlags & PassiveSubtreeFlags) !== NoSubtreeFlags ||
2111+
(finishedWork.subtreeFlags & PassiveMask) !== NoFlags ||
21562112
(finishedWork.flags & PassiveMask) !== NoFlags
21572113
) {
21582114
if (!rootDoesHavePassiveEffects) {
@@ -2306,9 +2262,8 @@ function commitBeforeMutationEffects(firstChild: Fiber) {
23062262
}
23072263

23082264
if (fiber.child !== null) {
2309-
const primarySubtreeFlags =
2310-
fiber.subtreeFlags & BeforeMutationSubtreeFlags;
2311-
if (primarySubtreeFlags !== NoSubtreeFlags) {
2265+
const primarySubtreeFlags = fiber.subtreeFlags & BeforeMutationMask;
2266+
if (primarySubtreeFlags !== NoFlags) {
23122267
commitBeforeMutationEffects(fiber.child);
23132268
}
23142269
}
@@ -2402,8 +2357,8 @@ function commitMutationEffects(
24022357
}
24032358

24042359
if (fiber.child !== null) {
2405-
const primarySubtreeFlags = fiber.subtreeFlags & MutationSubtreeFlags;
2406-
if (primarySubtreeFlags !== NoSubtreeFlags) {
2360+
const mutationFlags = fiber.subtreeFlags & MutationMask;
2361+
if (mutationFlags !== NoFlags) {
24072362
commitMutationEffects(fiber.child, root, renderPriorityLevel);
24082363
}
24092364
}
@@ -2560,8 +2515,8 @@ function commitLayoutEffects(
25602515
let fiber = firstChild;
25612516
while (fiber !== null) {
25622517
if (fiber.child !== null) {
2563-
const primarySubtreeFlags = fiber.subtreeFlags & LayoutSubtreeFlags;
2564-
if (primarySubtreeFlags !== NoSubtreeFlags) {
2518+
const primarySubtreeFlags = fiber.subtreeFlags & LayoutMask;
2519+
if (primarySubtreeFlags !== NoFlags) {
25652520
commitLayoutEffects(fiber.child, root, committedLanes);
25662521
}
25672522
}
@@ -2662,9 +2617,9 @@ export function enqueuePendingPassiveProfilerEffect(fiber: Fiber): void {
26622617
function flushPassiveMountEffects(firstChild: Fiber): void {
26632618
let fiber = firstChild;
26642619
while (fiber !== null) {
2665-
const primarySubtreeFlags = fiber.subtreeFlags & PassiveSubtreeFlags;
2620+
const primarySubtreeFlags = fiber.subtreeFlags & PassiveMask;
26662621

2667-
if (fiber.child !== null && primarySubtreeFlags !== NoSubtreeFlags) {
2622+
if (fiber.child !== null && primarySubtreeFlags !== NoFlags) {
26682623
flushPassiveMountEffects(fiber.child);
26692624
}
26702625

@@ -2698,8 +2653,8 @@ function flushPassiveUnmountEffects(firstChild: Fiber): void {
26982653
// Note that this requires checking subtreeFlags of the current Fiber,
26992654
// rather than the subtreeFlags/effectsTag of the first child,
27002655
// since that would not cover passive effects in siblings.
2701-
const primarySubtreeFlags = fiber.subtreeFlags & PassiveSubtreeFlags;
2702-
if (primarySubtreeFlags !== NoSubtreeFlags) {
2656+
const passiveFlags = fiber.subtreeFlags & PassiveMask;
2657+
if (passiveFlags !== NoFlags) {
27032658
flushPassiveUnmountEffects(child);
27042659
}
27052660
}
@@ -2719,10 +2674,7 @@ function flushPassiveUnmountEffectsInsideOfDeletedTree(
27192674
fiberToDelete: Fiber,
27202675
nearestMountedAncestor: Fiber,
27212676
): void {
2722-
if (
2723-
(fiberToDelete.subtreeFlags & PassiveStaticSubtreeFlags) !==
2724-
NoSubtreeFlags
2725-
) {
2677+
if ((fiberToDelete.subtreeFlags & PassiveStatic) !== NoFlags) {
27262678
// If any children have passive effects then traverse the subtree.
27272679
// Note that this requires checking subtreeFlags of the current Fiber,
27282680
// rather than the subtreeFlags/effectsTag of the first child,

packages/react-reconciler/src/ReactInternalTypes.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import type {SuspenseInstance} from './ReactFiberHostConfig';
2020
import type {WorkTag} from './ReactWorkTags';
2121
import type {TypeOfMode} from './ReactTypeOfMode';
2222
import type {Flags} from './ReactFiberFlags';
23-
import type {SubtreeFlags} from './ReactSubtreeFlags';
2423
import type {Lane, LanePriority, Lanes, LaneMap} from './ReactFiberLane';
2524
import type {HookType} from './ReactFiberHooks.old';
2625
import type {RootTag} from './ReactRootTags';
@@ -119,7 +118,7 @@ export type Fiber = {|
119118

120119
// Effect
121120
flags: Flags,
122-
subtreeFlags: SubtreeFlags,
121+
subtreeFlags: Flags,
123122
deletions: Array<Fiber> | null,
124123

125124
// Singly linked list fast path to the next fiber with side-effects.

packages/react-reconciler/src/ReactSubtreeFlags.js

-18
This file was deleted.

0 commit comments

Comments
 (0)