Skip to content

Commit 8df7b79

Browse files
authored
Remove Passive flag from "before mutation" phase (#20038)
We don't need to visit passive effect nodes during before mutation. The only reason we were previously was to schedule the root-level passive effect callback as early as possible, but now that `subtreeFlags` exists, we can check that instead. This should reduce the amount of traversal during the commit phase, particularly when mounting or updating large trees that contain many passive effects.
1 parent 2eb3181 commit 8df7b79

File tree

2 files changed

+18
-27
lines changed

2 files changed

+18
-27
lines changed

packages/react-reconciler/src/ReactFiberFlags.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ export const ForceUpdateForLegacySuspense = /* */ 0b000100000000000000;
4848
export const PassiveStatic = /* */ 0b001000000000000000;
4949

5050
// Union of side effect groupings as pertains to subtreeFlags
51-
export const BeforeMutationMask = /* */ 0b000000001100001010;
51+
// TODO: Don't need to visit Placement during BeforeMutation phase
52+
// TODO: Only need to visit Deletions during BeforeMutation phase if an element
53+
// is focused.
54+
export const BeforeMutationMask = /* */ 0b000000000100001010;
5255
export const MutationMask = /* */ 0b000000010010011110;
5356
export const LayoutMask = /* */ 0b000000000010100100;
5457
export const PassiveMask = /* */ 0b000000001000001000;

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

+14-26
Original file line numberDiff line numberDiff line change
@@ -1880,6 +1880,20 @@ function commitRootImpl(root, renderPriorityLevel) {
18801880
NoFlags;
18811881

18821882
if (subtreeHasEffects || rootHasEffect) {
1883+
// If there are pending passive effects, schedule a callback to process them.
1884+
if (
1885+
(finishedWork.subtreeFlags & PassiveMask) !== NoFlags ||
1886+
(finishedWork.flags & PassiveMask) !== NoFlags
1887+
) {
1888+
if (!rootDoesHavePassiveEffects) {
1889+
rootDoesHavePassiveEffects = true;
1890+
scheduleCallback(NormalSchedulerPriority, () => {
1891+
flushPassiveEffects();
1892+
return null;
1893+
});
1894+
}
1895+
}
1896+
18831897
let previousLanePriority;
18841898
if (decoupleUpdatePriorityFromScheduler) {
18851899
previousLanePriority = getCurrentUpdateLanePriority();
@@ -1972,20 +1986,6 @@ function commitRootImpl(root, renderPriorityLevel) {
19721986
markLayoutEffectsStopped();
19731987
}
19741988

1975-
// If there are pending passive effects, schedule a callback to process them.
1976-
if (
1977-
(finishedWork.subtreeFlags & PassiveMask) !== NoFlags ||
1978-
(finishedWork.flags & PassiveMask) !== NoFlags
1979-
) {
1980-
if (!rootDoesHavePassiveEffects) {
1981-
rootDoesHavePassiveEffects = true;
1982-
scheduleCallback(NormalSchedulerPriority, () => {
1983-
flushPassiveEffects();
1984-
return null;
1985-
});
1986-
}
1987-
}
1988-
19891989
// Tell Scheduler to yield at the end of the frame, so the browser has an
19901990
// opportunity to paint.
19911991
requestPaint();
@@ -2181,18 +2181,6 @@ function commitBeforeMutationEffectsImpl(fiber: Fiber) {
21812181
commitBeforeMutationEffectOnFiber(current, fiber);
21822182
resetCurrentDebugFiberInDEV();
21832183
}
2184-
2185-
if ((flags & Passive) !== NoFlags) {
2186-
// If there are passive effects, schedule a callback to flush at
2187-
// the earliest opportunity.
2188-
if (!rootDoesHavePassiveEffects) {
2189-
rootDoesHavePassiveEffects = true;
2190-
scheduleCallback(NormalSchedulerPriority, () => {
2191-
flushPassiveEffects();
2192-
return null;
2193-
});
2194-
}
2195-
}
21962184
}
21972185

21982186
function commitBeforeMutationEffectsDeletions(deletions: Array<Fiber>) {

0 commit comments

Comments
 (0)