Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't fire passive effects during initial mount of a hidden Offscreen…
… tree (#24967) * Change OffscreenInstance isHidden to bitmask The isHidden field of OffscreenInstance is a boolean that represents whether the tree is currently hidden. To implement resuable effects, we need to also track whether the passive effects are currently connected. So I've changed this field to a bitmask. No other behavior has changed in this commit. I'll update the effects behavior in the following steps. * Extract passive mount effects to separate functions I'm about to add a "reappear passive effects" function that will share much of the same code as commitPassiveMountEffectOnFiber. To minimize the duplicated code, I've extracted the shared parts into separate functions, similar to what I did for commitLayoutEffectOnFiber and reappearLayoutEffects. This may not save much on code size because Closure will likely inline some of it, anyway, but it makes it harder for the two paths to accidentally diverge. * Don't mount passive effects in a new hidden tree This changes the behavior of Offscreen so that passive effects do not fire when prerendering a brand new tree. Previously, Offscreen did not affect passive effects at all — only layout effects, which mount or unmount whenever the visibility of the tree changes. When hiding an already visible tree, the behavior of passive effects is unchanged, for now; unlike layout effects, the passive effects will not get unmounted. Pre-rendered updates to a hidden tree in this state will also fire normally. This is only temporary, though — the plan is for passive effects to act more like layout effects, and unmount them when the tree is hidden. Perhaps after a delay so that if the visibility toggles quickly back and forth, the effects don't need to remount. I'll implement this separately. * "Atomic" passive commit effects must always fire There are a few cases where commit phase logic always needs to fire even inside a hidden tree. In general, we should try to design algorithms that don't depend on a commit effect running during prerendering, but there's at least one case where I think it makes sense. The experimental Cache component uses reference counting to keep track of the lifetime of a cache instance. This allows us to expose an AbortSignal object that data frameworks can use to cancel aborted requests. These cache objects are considered alive even inside a prerendered tree. To implement this I added an "atomic" passive effect traversal that runs even when a tree is hidden. (As a follow up, we should add a special subtree flag so that we can skip over nodes that don't have them. There are a number of similar subtree flag optimizations that we have planned, so I'll leave them for a later refactor.) The only other feature that currently depends on this behavior is Transition Tracing. I did not add a test for this because Transition Tracing is still in development and doesn't yet work with Offscreen.
- Loading branch information