Add static version of Passive subtree tag (#19510)
Creates new subtree tag, PassiveStatic, that represents whether a tree contains any passive effect hooks. It corresponds to the PassiveStatic effect tag, which represents the same concept for an individual fiber. This allows us to remove the PassiveStatic effect tag from PassiveMask. Its presence was causing us to schedule a passive effect phase callback on every render, instead of only when something changed. That's now fixed; this is reflected in the SchedulerProfiler tests. (The naming is getting really confusing. Need to do some bikeshedding.)
Andrew Clark committed
Aug 1, 2020 at 08:15 UTC
93a0c2830534cfbc4e6be3ecc9c9fc34dee3cfaa
4 files changed
+18
-11
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+11
-3
@@ -149,6 +149,7 @@ import {
149
Mutation as MutationSubtreeTag,
150
Layout as LayoutSubtreeTag,
151
Passive as PassiveSubtreeTag,
152
+ PassiveStatic as PassiveStaticSubtreeTag,
153
} from './ReactSubtreeTags';
154
import {
155
NoLanePriority,
@@ -1901,6 +1902,9 @@ function resetChildLanes(completedWork: Fiber) {
1902
if ((effectTag & PassiveMask) !== NoEffect) {
1903
subtreeTag |= PassiveSubtreeTag;
1904
}
1905
+ if ((effectTag & PassiveStatic) !== NoEffect) {
1906
+ subtreeTag |= PassiveStaticSubtreeTag;
1907
+ }
1908
1909
// When a fiber is cloned, its actualDuration is reset to 0. This value will
1910
// only be updated if work is done on the fiber (i.e. it doesn't bailout).
@@ -1951,6 +1955,9 @@ function resetChildLanes(completedWork: Fiber) {
1955
if ((effectTag & PassiveMask) !== NoEffect) {
1956
subtreeTag |= PassiveSubtreeTag;
1957
}
1958
+ if ((effectTag & PassiveStatic) !== NoEffect) {
1959
+ subtreeTag |= PassiveStaticSubtreeTag;
1960
+ }
1961
1962
child = child.sibling;
1963
}
@@ -2784,8 +2791,9 @@ function flushPassiveUnmountEffects(firstChild: Fiber): void {
2791
for (let i = 0; i < deletions.length; i++) {
2792
const fiberToDelete = deletions[i];
2793
// If this fiber (or anything below it) has passive effects then traverse the subtree.
2787
- const primaryEffectTag = fiberToDelete.effectTag & PassiveMask;
2788
- const primarySubtreeTag = fiberToDelete.subtreeTag & PassiveSubtreeTag;
2794
+ const primaryEffectTag = fiberToDelete.effectTag & PassiveStatic;
2795
+ const primarySubtreeTag =
2796
+ fiberToDelete.subtreeTag & PassiveStaticSubtreeTag;
2797
if (
2798
primarySubtreeTag !== NoSubtreeTag ||
2799
primaryEffectTag !== NoEffect
@@ -2837,7 +2845,7 @@ function flushPassiveUnmountEffectsInsideOfDeletedTree(
2845
// Note that this requires checking subtreeTag of the current Fiber,
2846
// rather than the subtreeTag/effectsTag of the first child,
2847
// since that would not cover passive effects in siblings.
2840
- const primarySubtreeTag = fiber.subtreeTag & PassiveSubtreeTag;
2848
+ const primarySubtreeTag = fiber.subtreeTag & PassiveStaticSubtreeTag;
2849
if (primarySubtreeTag !== NoSubtreeTag) {
2850
flushPassiveUnmountEffectsInsideOfDeletedTree(child);
2851
}
packages/react-reconciler/src/ReactSideEffectTags.js
+1
-1
@@ -51,7 +51,7 @@ export const PassiveStatic = /* */ 0b1000000000000000;
51
export const BeforeMutationMask = /* */ 0b0000001100001010;
52
export const MutationMask = /* */ 0b0000010010011110;
53
export const LayoutMask = /* */ 0b0000000010100100;
54
-export const PassiveMask = /* */ 0b1000001000001000;
54
+export const PassiveMask = /* */ 0b0000001000001000;
55
56
// Union of tags that don't get reset on clones.
57
// This allows certain concepts to persist without recalculting them,
packages/react-reconciler/src/ReactSubtreeTags.js
+6
-5
@@ -9,8 +9,9 @@
9
10
export type SubtreeTag = number;
11
12
-export const NoEffect = /* */ 0b0000;
13
-export const BeforeMutation = /* */ 0b0001;
14
-export const Mutation = /* */ 0b0010;
15
-export const Layout = /* */ 0b0100;
16
-export const Passive = /* */ 0b1000;
12
+export const NoEffect = /* */ 0b00000;
13
+export const BeforeMutation = /* */ 0b00001;
14
+export const Mutation = /* */ 0b00010;
15
+export const Layout = /* */ 0b00100;
16
+export const Passive = /* */ 0b01000;
17
+export const PassiveStatic = /* */ 0b10000;
packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js
-2
@@ -526,8 +526,6 @@ describe('SchedulingProfiler', () => {
526
'--layout-effects-start-1024',
527
'--layout-effects-stop',
528
'--commit-stop',
529
- '--passive-effects-start-1024',
530
- '--passive-effects-stop',
529
]);
530
}
531
});