Skip to content

Commit d37d7a4

Browse files
committedDec 18, 2020
Convert passive mount phase to tree traversal
1 parent 19e15a3 commit d37d7a4

File tree

4 files changed

+248
-136
lines changed

4 files changed

+248
-136
lines changed
 

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

+121
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,15 @@ import {
6767
Placement,
6868
Snapshot,
6969
Update,
70+
Passive,
71+
PassiveMask,
7072
} from './ReactFiberFlags';
7173
import getComponentName from 'shared/getComponentName';
7274
import invariant from 'shared/invariant';
75+
import {
76+
resetCurrentFiber as resetCurrentDebugFiberInDEV,
77+
setCurrentFiber as setCurrentDebugFiberInDEV,
78+
} from './ReactCurrentFiber';
7379

7480
import {onCommitUnmount} from './ReactFiberDevToolsHook.new';
7581
import {resolveDefaultProps} from './ReactFiberLazyComponent.new';
@@ -78,6 +84,8 @@ import {
7884
getCommitTime,
7985
recordLayoutEffectDuration,
8086
startLayoutEffectTimer,
87+
recordPassiveEffectDuration,
88+
startPassiveEffectTimer,
8189
} from './ReactProfilerTimer.new';
8290
import {ProfileMode} from './ReactTypeOfMode';
8391
import {commitUpdateQueue} from './ReactUpdateQueue.new';
@@ -134,6 +142,8 @@ if (__DEV__) {
134142

135143
const PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
136144

145+
let nextEffect: Fiber | null = null;
146+
137147
const callComponentWillUnmountWithTimer = function(current, instance) {
138148
instance.props = current.memoizedProps;
139149
instance.state = current.memoizedState;
@@ -1798,6 +1808,117 @@ function commitResetTextContent(current: Fiber) {
17981808
resetTextContent(current.stateNode);
17991809
}
18001810

1811+
export function commitPassiveMountEffects(
1812+
root: FiberRoot,
1813+
firstChild: Fiber,
1814+
): void {
1815+
nextEffect = firstChild;
1816+
commitPassiveMountEffects_begin(firstChild, root);
1817+
}
1818+
1819+
function commitPassiveMountEffects_begin(subtreeRoot: Fiber, root: FiberRoot) {
1820+
while (nextEffect !== null) {
1821+
const fiber = nextEffect;
1822+
const firstChild = fiber.child;
1823+
if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) {
1824+
ensureCorrectReturnPointer(firstChild, fiber);
1825+
nextEffect = firstChild;
1826+
} else {
1827+
commitPassiveMountEffects_complete(subtreeRoot, root);
1828+
}
1829+
}
1830+
}
1831+
1832+
function commitPassiveMountEffects_complete(
1833+
subtreeRoot: Fiber,
1834+
root: FiberRoot,
1835+
) {
1836+
while (nextEffect !== null) {
1837+
const fiber = nextEffect;
1838+
if ((fiber.flags & Passive) !== NoFlags) {
1839+
if (__DEV__) {
1840+
setCurrentDebugFiberInDEV(fiber);
1841+
invokeGuardedCallback(
1842+
null,
1843+
commitPassiveMountOnFiber,
1844+
null,
1845+
root,
1846+
fiber,
1847+
);
1848+
if (hasCaughtError()) {
1849+
const error = clearCaughtError();
1850+
captureCommitPhaseError(fiber, error);
1851+
}
1852+
resetCurrentDebugFiberInDEV();
1853+
} else {
1854+
try {
1855+
commitPassiveMountOnFiber(root, fiber);
1856+
} catch (error) {
1857+
captureCommitPhaseError(fiber, error);
1858+
}
1859+
}
1860+
}
1861+
1862+
if (fiber === subtreeRoot) {
1863+
nextEffect = null;
1864+
return;
1865+
}
1866+
1867+
const sibling = fiber.sibling;
1868+
if (sibling !== null) {
1869+
ensureCorrectReturnPointer(sibling, fiber.return);
1870+
nextEffect = sibling;
1871+
return;
1872+
}
1873+
1874+
nextEffect = fiber.return;
1875+
}
1876+
}
1877+
1878+
function commitPassiveMountOnFiber(
1879+
finishedRoot: FiberRoot,
1880+
finishedWork: Fiber,
1881+
): void {
1882+
switch (finishedWork.tag) {
1883+
case FunctionComponent:
1884+
case ForwardRef:
1885+
case SimpleMemoComponent: {
1886+
if (
1887+
enableProfilerTimer &&
1888+
enableProfilerCommitHooks &&
1889+
finishedWork.mode & ProfileMode
1890+
) {
1891+
startPassiveEffectTimer();
1892+
try {
1893+
commitHookEffectListMount(HookPassive | HookHasEffect, finishedWork);
1894+
} finally {
1895+
recordPassiveEffectDuration(finishedWork);
1896+
}
1897+
} else {
1898+
commitHookEffectListMount(HookPassive | HookHasEffect, finishedWork);
1899+
}
1900+
break;
1901+
}
1902+
}
1903+
}
1904+
1905+
let didWarnWrongReturnPointer = false;
1906+
function ensureCorrectReturnPointer(fiber, expectedReturnFiber) {
1907+
if (__DEV__) {
1908+
if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) {
1909+
didWarnWrongReturnPointer = true;
1910+
console.error(
1911+
'Internal React error: Return pointer is inconsistent ' +
1912+
'with parent.',
1913+
);
1914+
}
1915+
}
1916+
1917+
// TODO: Remove this assignment once we're confident that it won't break
1918+
// anything, by checking the warning logs for the above invariant
1919+
fiber.return = expectedReturnFiber;
1920+
}
1921+
18011922
export {
18021923
commitBeforeMutationLifeCycles,
18031924
commitResetTextContent,

‎packages/react-reconciler/src/ReactFiberCommitWork.old.js

+121
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,15 @@ import {
6767
Placement,
6868
Snapshot,
6969
Update,
70+
Passive,
71+
PassiveMask,
7072
} from './ReactFiberFlags';
7173
import getComponentName from 'shared/getComponentName';
7274
import invariant from 'shared/invariant';
75+
import {
76+
resetCurrentFiber as resetCurrentDebugFiberInDEV,
77+
setCurrentFiber as setCurrentDebugFiberInDEV,
78+
} from './ReactCurrentFiber';
7379

7480
import {onCommitUnmount} from './ReactFiberDevToolsHook.old';
7581
import {resolveDefaultProps} from './ReactFiberLazyComponent.old';
@@ -78,6 +84,8 @@ import {
7884
getCommitTime,
7985
recordLayoutEffectDuration,
8086
startLayoutEffectTimer,
87+
recordPassiveEffectDuration,
88+
startPassiveEffectTimer,
8189
} from './ReactProfilerTimer.old';
8290
import {ProfileMode} from './ReactTypeOfMode';
8391
import {commitUpdateQueue} from './ReactUpdateQueue.old';
@@ -134,6 +142,8 @@ if (__DEV__) {
134142

135143
const PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
136144

145+
let nextEffect: Fiber | null = null;
146+
137147
const callComponentWillUnmountWithTimer = function(current, instance) {
138148
instance.props = current.memoizedProps;
139149
instance.state = current.memoizedState;
@@ -1798,6 +1808,117 @@ function commitResetTextContent(current: Fiber) {
17981808
resetTextContent(current.stateNode);
17991809
}
18001810

1811+
export function commitPassiveMountEffects(
1812+
root: FiberRoot,
1813+
firstChild: Fiber,
1814+
): void {
1815+
nextEffect = firstChild;
1816+
commitPassiveMountEffects_begin(firstChild, root);
1817+
}
1818+
1819+
function commitPassiveMountEffects_begin(subtreeRoot: Fiber, root: FiberRoot) {
1820+
while (nextEffect !== null) {
1821+
const fiber = nextEffect;
1822+
const firstChild = fiber.child;
1823+
if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) {
1824+
ensureCorrectReturnPointer(firstChild, fiber);
1825+
nextEffect = firstChild;
1826+
} else {
1827+
commitPassiveMountEffects_complete(subtreeRoot, root);
1828+
}
1829+
}
1830+
}
1831+
1832+
function commitPassiveMountEffects_complete(
1833+
subtreeRoot: Fiber,
1834+
root: FiberRoot,
1835+
) {
1836+
while (nextEffect !== null) {
1837+
const fiber = nextEffect;
1838+
if ((fiber.flags & Passive) !== NoFlags) {
1839+
if (__DEV__) {
1840+
setCurrentDebugFiberInDEV(fiber);
1841+
invokeGuardedCallback(
1842+
null,
1843+
commitPassiveMountOnFiber,
1844+
null,
1845+
root,
1846+
fiber,
1847+
);
1848+
if (hasCaughtError()) {
1849+
const error = clearCaughtError();
1850+
captureCommitPhaseError(fiber, error);
1851+
}
1852+
resetCurrentDebugFiberInDEV();
1853+
} else {
1854+
try {
1855+
commitPassiveMountOnFiber(root, fiber);
1856+
} catch (error) {
1857+
captureCommitPhaseError(fiber, error);
1858+
}
1859+
}
1860+
}
1861+
1862+
if (fiber === subtreeRoot) {
1863+
nextEffect = null;
1864+
return;
1865+
}
1866+
1867+
const sibling = fiber.sibling;
1868+
if (sibling !== null) {
1869+
ensureCorrectReturnPointer(sibling, fiber.return);
1870+
nextEffect = sibling;
1871+
return;
1872+
}
1873+
1874+
nextEffect = fiber.return;
1875+
}
1876+
}
1877+
1878+
function commitPassiveMountOnFiber(
1879+
finishedRoot: FiberRoot,
1880+
finishedWork: Fiber,
1881+
): void {
1882+
switch (finishedWork.tag) {
1883+
case FunctionComponent:
1884+
case ForwardRef:
1885+
case SimpleMemoComponent: {
1886+
if (
1887+
enableProfilerTimer &&
1888+
enableProfilerCommitHooks &&
1889+
finishedWork.mode & ProfileMode
1890+
) {
1891+
startPassiveEffectTimer();
1892+
try {
1893+
commitHookEffectListMount(HookPassive | HookHasEffect, finishedWork);
1894+
} finally {
1895+
recordPassiveEffectDuration(finishedWork);
1896+
}
1897+
} else {
1898+
commitHookEffectListMount(HookPassive | HookHasEffect, finishedWork);
1899+
}
1900+
break;
1901+
}
1902+
}
1903+
}
1904+
1905+
let didWarnWrongReturnPointer = false;
1906+
function ensureCorrectReturnPointer(fiber, expectedReturnFiber) {
1907+
if (__DEV__) {
1908+
if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) {
1909+
didWarnWrongReturnPointer = true;
1910+
console.error(
1911+
'Internal React error: Return pointer is inconsistent ' +
1912+
'with parent.',
1913+
);
1914+
}
1915+
}
1916+
1917+
// TODO: Remove this assignment once we're confident that it won't break
1918+
// anything, by checking the warning logs for the above invariant
1919+
fiber.return = expectedReturnFiber;
1920+
}
1921+
18011922
export {
18021923
commitBeforeMutationLifeCycles,
18031924
commitResetTextContent,

0 commit comments

Comments
 (0)