@samitouri / QOS-React / commits / 8df7b7911a

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.

Andrew Clark committed Oct 16, 2020 at 08:21 UTC 8df7b7911aa7fc3a896fb29da29e09f574e931aa
2 files changed +18 -27
packages/react-reconciler/src/ReactFiberFlags.js
+4 -1
@@ -48,7 +48,10 @@ export const ForceUpdateForLegacySuspense = /* */ 0b000100000000000000;
48 export const PassiveStatic = /* */ 0b001000000000000000;
49
50 // 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;
55 export const MutationMask = /* */ 0b000000010010011110;
56 export const LayoutMask = /* */ 0b000000000010100100;
57 export const PassiveMask = /* */ 0b000000001000001000;
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+14 -26
@@ -1880,6 +1880,20 @@ function commitRootImpl(root, renderPriorityLevel) {
1880 NoFlags;
1881
1882 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 +
1897 let previousLanePriority;
1898 if (decoupleUpdatePriorityFromScheduler) {
1899 previousLanePriority = getCurrentUpdateLanePriority();
@@ -1972,20 +1986,6 @@ function commitRootImpl(root, renderPriorityLevel) {
1986 markLayoutEffectsStopped();
1987 }
1988
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 -
1989 // Tell Scheduler to yield at the end of the frame, so the browser has an
1990 // opportunity to paint.
1991 requestPaint();
@@ -2181,18 +2181,6 @@ function commitBeforeMutationEffectsImpl(fiber: Fiber) {
2181 commitBeforeMutationEffectOnFiber(current, fiber);
2182 resetCurrentDebugFiberInDEV();
2183 }
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 - }
2184 }
2185
2186 function commitBeforeMutationEffectsDeletions(deletions: Array<Fiber>) {