Skip to content

Commit

Permalink
Revert "Clean up host pointers in level 2 of clean-up flag (#21112)"
Browse files Browse the repository at this point in the history
This reverts commit 8ed0c85.

The host tree is a cyclical structure. Leaking a single DOM node can
retain a large amount of memory. React-managed DOM nodes also point
back to a fiber tree.

Perf testing suggests that disconnecting these fields has a big memory
impact. That suggests leaks in non-React code but since it's hard to
completely eliminate those, it may still be worth the extra work to
clear these fields.

I'm moving this to level 2 to confirm whether this alone is responsible
for the memory savings, or if there are other fields that are retaining
large amounts of memory.

In our plan for removing the alternate model, DOM nodes would not be
connected to fibers, except at the root of the whole tree, which is
easy to disconnect on deletion. So in that world, we likely won't have
to do any additional work.
  • Loading branch information
acdlite committed Apr 28, 2021
1 parent 1bd41c6 commit c670265
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 24 deletions.
21 changes: 9 additions & 12 deletions packages/react-reconciler/src/ReactFiberCommitWork.new.js
Expand Up @@ -1382,18 +1382,6 @@ function detachFiberAfterEffects(fiber: Fiber) {
fiber.deletions = null;
fiber.sibling = null;

// The `stateNode` is cyclical because on host nodes it points to the host
// tree, which has its own pointers to children, parents, and siblings.
// The other host nodes also point back to fibers, so we should detach that
// one, too.
if (fiber.tag === HostComponent) {
const hostInstance: Instance = fiber.stateNode;
if (hostInstance !== null) {
detachDeletedInstance(hostInstance);
}
}
fiber.stateNode = null;

// I'm intentionally not clearing the `return` field in this level. We
// already disconnect the `return` pointer at the root of the deleted
// subtree (in `detachFiberMutation`). Besides, `return` by itself is not
Expand All @@ -1412,6 +1400,15 @@ function detachFiberAfterEffects(fiber: Fiber) {
// The purpose of this branch is to be super aggressive so we can measure
// if there's any difference in memory impact. If there is, that could
// indicate a React leak we don't know about.

// For host components, disconnect host instance -> fiber pointer.
if (fiber.tag === HostComponent) {
const hostInstance: Instance = fiber.stateNode;
if (hostInstance !== null) {
detachDeletedInstance(hostInstance);
}
}

fiber.return = null;
fiber.dependencies = null;
fiber.memoizedProps = null;
Expand Down
21 changes: 9 additions & 12 deletions packages/react-reconciler/src/ReactFiberCommitWork.old.js
Expand Up @@ -1382,18 +1382,6 @@ function detachFiberAfterEffects(fiber: Fiber) {
fiber.deletions = null;
fiber.sibling = null;

// The `stateNode` is cyclical because on host nodes it points to the host
// tree, which has its own pointers to children, parents, and siblings.
// The other host nodes also point back to fibers, so we should detach that
// one, too.
if (fiber.tag === HostComponent) {
const hostInstance: Instance = fiber.stateNode;
if (hostInstance !== null) {
detachDeletedInstance(hostInstance);
}
}
fiber.stateNode = null;

// I'm intentionally not clearing the `return` field in this level. We
// already disconnect the `return` pointer at the root of the deleted
// subtree (in `detachFiberMutation`). Besides, `return` by itself is not
Expand All @@ -1412,6 +1400,15 @@ function detachFiberAfterEffects(fiber: Fiber) {
// The purpose of this branch is to be super aggressive so we can measure
// if there's any difference in memory impact. If there is, that could
// indicate a React leak we don't know about.

// For host components, disconnect host instance -> fiber pointer.
if (fiber.tag === HostComponent) {
const hostInstance: Instance = fiber.stateNode;
if (hostInstance !== null) {
detachDeletedInstance(hostInstance);
}
}

fiber.return = null;
fiber.dependencies = null;
fiber.memoizedProps = null;
Expand Down

0 comments on commit c670265

Please sign in to comment.