@@ -46,7 +46,6 @@ import {
4646 enableSchedulingProfiler ,
4747 enableSuspenseCallback ,
4848 enableScopeAPI ,
49- deletedTreeCleanUpLevel ,
5049 enableUpdaterTracking ,
5150 enableCache ,
5251 enableTransitionTracing ,
@@ -1658,74 +1657,43 @@ function detachFiberAfterEffects(fiber: Fiber) {
16581657 detachFiberAfterEffects ( alternate ) ;
16591658 }
16601659
1661- // Note: Defensively using negation instead of < in case
1662- // `deletedTreeCleanUpLevel` is undefined.
1663- if ( ! ( deletedTreeCleanUpLevel > = 2)) {
1664- // This is the default branch (level 0).
1665- fiber . child = null ;
1666- fiber . deletions = null ;
1667- fiber . dependencies = null ;
1668- fiber . memoizedProps = null ;
1669- fiber . memoizedState = null ;
1670- fiber . pendingProps = null ;
1671- fiber . sibling = null ;
1672- fiber . stateNode = null ;
1673- fiber . updateQueue = null ;
1674-
1675- if ( __DEV__ ) {
1676- fiber . _debugOwner = null ;
1660+ // Clear cyclical Fiber fields. This level alone is designed to roughly
1661+ // approximate the planned Fiber refactor. In that world, `setState` will be
1662+ // bound to a special "instance" object instead of a Fiber. The Instance
1663+ // object will not have any of these fields. It will only be connected to
1664+ // the fiber tree via a single link at the root. So if this level alone is
1665+ // sufficient to fix memory issues, that bodes well for our plans.
1666+ fiber.child = null;
1667+ fiber.deletions = null;
1668+ fiber.sibling = null;
1669+
1670+ // The `stateNode` is cyclical because on host nodes it points to the host
1671+ // tree, which has its own pointers to children, parents, and siblings.
1672+ // The other host nodes also point back to fibers, so we should detach that
1673+ // one, too.
1674+ if (fiber.tag === HostComponent) {
1675+ const hostInstance : Instance = fiber . stateNode ;
1676+ if ( hostInstance !== null ) {
1677+ detachDeletedInstance ( hostInstance ) ;
16771678 }
1678- } else {
1679- // Clear cyclical Fiber fields. This level alone is designed to roughly
1680- // approximate the planned Fiber refactor. In that world, `setState` will be
1681- // bound to a special "instance" object instead of a Fiber. The Instance
1682- // object will not have any of these fields. It will only be connected to
1683- // the fiber tree via a single link at the root. So if this level alone is
1684- // sufficient to fix memory issues, that bodes well for our plans.
1685- fiber . child = null ;
1686- fiber . deletions = null ;
1687- fiber . sibling = null ;
1688-
1689- // The `stateNode` is cyclical because on host nodes it points to the host
1690- // tree, which has its own pointers to children, parents, and siblings.
1691- // The other host nodes also point back to fibers, so we should detach that
1692- // one, too.
1693- if ( fiber . tag === HostComponent ) {
1694- const hostInstance : Instance = fiber . stateNode ;
1695- if ( hostInstance !== null ) {
1696- detachDeletedInstance ( hostInstance ) ;
1697- }
1698- }
1699- fiber.stateNode = null;
1700-
1701- // I'm intentionally not clearing the `return` field in this level. We
1702- // already disconnect the `return` pointer at the root of the deleted
1703- // subtree (in `detachFiberMutation`). Besides, `return` by itself is not
1704- // cyclical — it's only cyclical when combined with `child`, `sibling`, and
1705- // `alternate`. But we'll clear it in the next level anyway, just in case.
1679+ }
1680+ fiber.stateNode = null;
17061681
1707- if (__DEV__) {
1708- fiber . _debugOwner = null ;
1709- }
1710-
1711- if (deletedTreeCleanUpLevel >= 3 ) {
1712- // Theoretically, nothing in here should be necessary, because we already
1713- // disconnected the fiber from the tree. So even if something leaks this
1714- // particular fiber, it won't leak anything else
1715- //
1716- // The purpose of this branch is to be super aggressive so we can measure
1717- // if there's any difference in memory impact. If there is, that could
1718- // indicate a React leak we don't know about.
1719- fiber . return = null ;
1720- fiber . dependencies = null ;
1721- fiber . memoizedProps = null ;
1722- fiber . memoizedState = null ;
1723- fiber . pendingProps = null ;
1724- fiber . stateNode = null ;
1725- // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead.
1726- fiber . updateQueue = null ;
1727- }
1682+ if (__DEV__) {
1683+ fiber . _debugOwner = null ;
17281684 }
1685+
1686+ // Theoretically, nothing in here should be necessary, because we already
1687+ // disconnected the fiber from the tree. So even if something leaks this
1688+ // particular fiber, it won't leak anything else.
1689+ fiber.return = null;
1690+ fiber.dependencies = null;
1691+ fiber.memoizedProps = null;
1692+ fiber.memoizedState = null;
1693+ fiber.pendingProps = null;
1694+ fiber.stateNode = null;
1695+ // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead.
1696+ fiber.updateQueue = null;
17291697}
17301698
17311699function emptyPortalContainer ( current : Fiber ) {
@@ -3986,31 +3954,29 @@ export function commitPassiveUnmountEffects(finishedWork: Fiber): void {
39863954}
39873955
39883956function detachAlternateSiblings ( parentFiber : Fiber ) {
3989- if ( deletedTreeCleanUpLevel >= 1 ) {
3990- // A fiber was deleted from this parent fiber, but it's still part of the
3991- // previous (alternate) parent fiber's list of children. Because children
3992- // are a linked list, an earlier sibling that's still alive will be
3993- // connected to the deleted fiber via its `alternate`:
3994- //
3995- // live fiber --alternate--> previous live fiber --sibling--> deleted
3996- // fiber
3997- //
3998- // We can't disconnect `alternate` on nodes that haven't been deleted yet,
3999- // but we can disconnect the `sibling` and `child` pointers.
4000-
4001- const previousFiber = parentFiber . alternate ;
4002- if ( previousFiber !== null ) {
4003- let detachedChild = previousFiber . child ;
4004- if ( detachedChild !== null ) {
4005- previousFiber . child = null ;
4006- do {
4007- // $FlowFixMe[incompatible-use] found when upgrading Flow
4008- const detachedSibling = detachedChild . sibling ;
4009- // $FlowFixMe[incompatible-use] found when upgrading Flow
4010- detachedChild . sibling = null ;
4011- detachedChild = detachedSibling ;
4012- } while ( detachedChild !== null ) ;
4013- }
3957+ // A fiber was deleted from this parent fiber, but it's still part of the
3958+ // previous (alternate) parent fiber's list of children. Because children
3959+ // are a linked list, an earlier sibling that's still alive will be
3960+ // connected to the deleted fiber via its `alternate`:
3961+ //
3962+ // live fiber --alternate--> previous live fiber --sibling--> deleted
3963+ // fiber
3964+ //
3965+ // We can't disconnect `alternate` on nodes that haven't been deleted yet,
3966+ // but we can disconnect the `sibling` and `child` pointers.
3967+
3968+ const previousFiber = parentFiber . alternate ;
3969+ if ( previousFiber !== null ) {
3970+ let detachedChild = previousFiber . child ;
3971+ if ( detachedChild !== null ) {
3972+ previousFiber . child = null ;
3973+ do {
3974+ // $FlowFixMe[incompatible-use] found when upgrading Flow
3975+ const detachedSibling = detachedChild . sibling ;
3976+ // $FlowFixMe[incompatible-use] found when upgrading Flow
3977+ detachedChild . sibling = null ;
3978+ detachedChild = detachedSibling ;
3979+ } while ( detachedChild !== null ) ;
40143980 }
40153981 }
40163982}
@@ -4196,8 +4162,7 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(
41964162 resetCurrentDebugFiberInDEV ( ) ;
41974163
41984164 const child = fiber . child ;
4199- // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we
4200- // do this, still need to handle `deletedTreeCleanUpLevel` correctly.)
4165+ // TODO: Only traverse subtree if it has a PassiveStatic flag.
42014166 if ( child !== null ) {
42024167 child . return = fiber ;
42034168 nextEffect = child ;
@@ -4217,23 +4182,13 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(
42174182 const sibling = fiber . sibling ;
42184183 const returnFiber = fiber . return ;
42194184
4220- if ( deletedTreeCleanUpLevel >= 2 ) {
4221- // Recursively traverse the entire deleted tree and clean up fiber fields.
4222- // This is more aggressive than ideal, and the long term goal is to only
4223- // have to detach the deleted tree at the root.
4224- detachFiberAfterEffects ( fiber ) ;
4225- if ( fiber === deletedSubtreeRoot ) {
4226- nextEffect = null ;
4227- return ;
4228- }
4229- } else {
4230- // This is the default branch (level 0). We do not recursively clear all
4231- // the fiber fields. Only the root of the deleted subtree.
4232- if ( fiber === deletedSubtreeRoot ) {
4233- detachFiberAfterEffects ( fiber ) ;
4234- nextEffect = null ;
4235- return ;
4236- }
4185+ // Recursively traverse the entire deleted tree and clean up fiber fields.
4186+ // This is more aggressive than ideal, and the long term goal is to only
4187+ // have to detach the deleted tree at the root.
4188+ detachFiberAfterEffects ( fiber ) ;
4189+ if ( fiber === deletedSubtreeRoot ) {
4190+ nextEffect = null ;
4191+ return ;
42374192 }
42384193
42394194 if ( sibling !== null ) {
0 commit comments