Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't fire passive effects during initial mount of a hidden Offscreen tree #24967

Merged
merged 4 commits into from
Jul 29, 2022

Conversation

acdlite
Copy link
Collaborator

@acdlite acdlite commented Jul 21, 2022

(You can review commit-by-commit. Pretend the commits are a stack of PRs, please.)

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.

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Jul 21, 2022
@sizebot
Copy link

sizebot commented Jul 21, 2022

Comparing: 6b28bc9...e6a705b

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.min.js +0.51% 132.92 kB 133.60 kB +0.35% 42.68 kB 42.83 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js +0.74% 138.15 kB 139.17 kB +0.59% 44.19 kB 44.45 kB
facebook-www/ReactDOM-prod.classic.js +1.19% 469.02 kB 474.61 kB +0.70% 84.22 kB 84.81 kB
facebook-www/ReactDOM-prod.modern.js +1.23% 454.26 kB 459.85 kB +0.72% 81.98 kB 82.57 kB
facebook-www/ReactDOMForked-prod.classic.js +1.19% 469.02 kB 474.61 kB +0.70% 84.22 kB 84.81 kB
facebook-react-native/react-test-renderer/cjs/ReactTestRenderer-prod.js +2.27% 269.48 kB 275.60 kB +1.19% 48.47 kB 49.05 kB
facebook-react-native/react-test-renderer/cjs/ReactTestRenderer-profiling.js +2.11% 284.72 kB 290.71 kB +1.17% 50.71 kB 51.31 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
facebook-react-native/react-test-renderer/cjs/ReactTestRenderer-prod.js +2.27% 269.48 kB 275.60 kB +1.19% 48.47 kB 49.05 kB
facebook-react-native/react-test-renderer/cjs/ReactTestRenderer-profiling.js +2.11% 284.72 kB 290.71 kB +1.17% 50.71 kB 51.31 kB
facebook-www/ReactART-prod.modern.js +1.88% 295.45 kB 301.02 kB +1.07% 51.35 kB 51.90 kB
facebook-www/ReactART-prod.classic.js +1.82% 306.29 kB 311.85 kB +1.04% 53.19 kB 53.75 kB
facebook-react-native/react-test-renderer/cjs/ReactTestRenderer-dev.js +1.59% 706.12 kB 717.36 kB +0.91% 152.08 kB 153.46 kB
facebook-www/ReactTestRenderer-dev.modern.js +1.54% 728.29 kB 739.53 kB +0.89% 156.17 kB 157.56 kB
facebook-www/ReactTestRenderer-dev.classic.js +1.54% 728.30 kB 739.53 kB +0.89% 156.17 kB 157.56 kB
react-native/implementations/ReactFabric-prod.js +1.54% 299.58 kB 304.20 kB +0.71% 53.58 kB 53.97 kB
react-native/implementations/ReactFabric-prod.fb.js +1.50% 307.92 kB 312.54 kB +0.69% 55.21 kB 55.60 kB
oss-experimental/react-test-renderer/cjs/react-test-renderer.development.js +1.50% 692.49 kB 702.89 kB +0.86% 150.56 kB 151.86 kB
oss-experimental/react-test-renderer/umd/react-test-renderer.development.js +1.49% 725.54 kB 736.38 kB +0.82% 152.27 kB 153.52 kB
react-native/implementations/ReactFabric-profiling.js +1.44% 318.57 kB 323.15 kB +0.68% 56.72 kB 57.11 kB
oss-experimental/react-art/cjs/react-art.development.js +1.44% 721.46 kB 731.82 kB +0.81% 156.07 kB 157.32 kB
facebook-www/ReactDOMTesting-prod.modern.js +1.41% 428.25 kB 434.28 kB +0.71% 79.65 kB 80.21 kB
react-native/implementations/ReactNativeRenderer-prod.js +1.39% 306.75 kB 311.01 kB +0.72% 54.69 kB 55.08 kB
react-native/implementations/ReactFabric-profiling.fb.js +1.36% 334.94 kB 339.50 kB +0.64% 59.42 kB 59.80 kB
facebook-www/ReactDOMTesting-prod.classic.js +1.36% 444.24 kB 450.28 kB +0.69% 82.06 kB 82.63 kB
react-native/implementations/ReactNativeRenderer-prod.fb.js +1.35% 315.08 kB 319.34 kB +0.70% 56.31 kB 56.70 kB
facebook-www/ReactART-dev.modern.js +1.34% 805.37 kB 816.16 kB +0.73% 170.93 kB 172.19 kB
facebook-www/ReactART-dev.classic.js +1.32% 815.59 kB 826.38 kB +0.73% 173.05 kB 174.32 kB
oss-experimental/react-reconciler/cjs/react-reconciler.development.js +1.31% 788.44 kB 798.79 kB +0.72% 168.11 kB 169.32 kB
oss-experimental/react-art/umd/react-art.development.js +1.31% 826.73 kB 837.53 kB +0.74% 174.17 kB 175.46 kB
react-native/implementations/ReactNativeRenderer-profiling.js +1.30% 325.79 kB 330.01 kB +0.69% 57.77 kB 58.17 kB
facebook-www/ReactDOM-prod.modern.js +1.23% 454.26 kB 459.85 kB +0.72% 81.98 kB 82.57 kB
facebook-www/ReactDOMForked-prod.modern.js +1.23% 454.26 kB 459.85 kB +0.72% 81.98 kB 82.57 kB
react-native/implementations/ReactNativeRenderer-profiling.fb.js +1.23% 342.14 kB 346.35 kB +0.65% 60.44 kB 60.84 kB
facebook-www/ReactDOM-prod.classic.js +1.19% 469.02 kB 474.61 kB +0.70% 84.22 kB 84.81 kB
facebook-www/ReactDOMForked-prod.classic.js +1.19% 469.02 kB 474.61 kB +0.70% 84.22 kB 84.81 kB
oss-experimental/react-art/cjs/react-art.production.min.js +1.17% 87.55 kB 88.58 kB +0.96% 27.17 kB 27.44 kB
facebook-www/ReactDOM-profiling.modern.js +1.13% 484.66 kB 490.15 kB +0.71% 86.47 kB 87.08 kB
facebook-www/ReactDOMForked-profiling.modern.js +1.13% 484.66 kB 490.15 kB +0.71% 86.47 kB 87.08 kB
oss-stable-semver/react-test-renderer/cjs/react-test-renderer.development.js +1.11% 666.62 kB 674.04 kB +0.64% 145.28 kB 146.21 kB
oss-stable/react-test-renderer/cjs/react-test-renderer.development.js +1.11% 666.65 kB 674.06 kB +0.64% 145.31 kB 146.23 kB
oss-stable-semver/react-test-renderer/umd/react-test-renderer.development.js +1.10% 698.38 kB 706.10 kB +0.66% 146.85 kB 147.82 kB
oss-stable/react-test-renderer/umd/react-test-renderer.development.js +1.10% 698.41 kB 706.12 kB +0.66% 146.87 kB 147.85 kB
facebook-www/ReactDOM-profiling.classic.js +1.10% 499.48 kB 504.97 kB +0.67% 88.80 kB 89.40 kB
facebook-www/ReactDOMForked-profiling.classic.js +1.10% 499.48 kB 504.97 kB +0.67% 88.80 kB 89.40 kB
oss-experimental/react-test-renderer/cjs/react-test-renderer.production.min.js +1.09% 94.47 kB 95.49 kB +0.91% 29.18 kB 29.45 kB
oss-experimental/react-test-renderer/umd/react-test-renderer.production.min.js +1.08% 94.72 kB 95.74 kB +0.96% 29.54 kB 29.83 kB
facebook-www/ReactDOMTesting-dev.modern.js +1.06% 1,061.51 kB 1,072.81 kB +0.56% 238.01 kB 239.35 kB
oss-stable-semver/react-art/cjs/react-art.development.js +1.06% 693.79 kB 701.16 kB +0.64% 150.17 kB 151.13 kB
oss-stable/react-art/cjs/react-art.development.js +1.06% 693.81 kB 701.19 kB +0.64% 150.20 kB 151.15 kB
react-native/implementations/ReactFabric-dev.js +1.05% 786.52 kB 794.75 kB +0.60% 171.07 kB 172.11 kB
oss-experimental/react-reconciler/cjs/react-reconciler.production.min.js +1.04% 98.96 kB 99.98 kB +0.96% 30.37 kB 30.66 kB
facebook-www/ReactDOMTesting-dev.classic.js +1.04% 1,090.13 kB 1,101.43 kB +0.55% 243.83 kB 245.17 kB
react-native/implementations/ReactNativeRenderer-dev.js +1.03% 796.21 kB 804.45 kB +0.61% 173.66 kB 174.71 kB
react-native/implementations/ReactFabric-dev.fb.js +1.00% 823.63 kB 831.83 kB +0.59% 177.75 kB 178.80 kB
react-native/implementations/ReactNativeRenderer-dev.fb.js +0.98% 833.30 kB 841.51 kB +0.57% 180.40 kB 181.44 kB
oss-experimental/react-dom/cjs/react-dom-unstable_testing.development.js +0.97% 1,062.85 kB 1,073.21 kB +0.53% 238.54 kB 239.79 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler.development.js +0.97% 760.48 kB 767.86 kB +0.61% 162.17 kB 163.17 kB
oss-stable/react-reconciler/cjs/react-reconciler.development.js +0.97% 760.51 kB 767.88 kB +0.61% 162.20 kB 163.19 kB
oss-experimental/react-dom/cjs/react-dom.development.js +0.97% 1,070.81 kB 1,081.17 kB +0.53% 239.82 kB 241.10 kB
oss-stable-semver/react-art/umd/react-art.development.js +0.96% 797.73 kB 805.40 kB +0.57% 168.32 kB 169.28 kB
oss-stable/react-art/umd/react-art.development.js +0.96% 797.75 kB 805.42 kB +0.57% 168.34 kB 169.30 kB
oss-experimental/react-dom/umd/react-dom.development.js +0.96% 1,123.28 kB 1,134.07 kB +0.52% 242.49 kB 243.75 kB
oss-experimental/react-reconciler/cjs/react-reconciler.profiling.min.js +0.94% 107.86 kB 108.88 kB +0.66% 32.65 kB 32.87 kB
facebook-www/ReactDOMForked-dev.modern.js +0.92% 1,177.52 kB 1,188.31 kB +0.48% 258.84 kB 260.09 kB
facebook-www/ReactDOM-dev.modern.js +0.92% 1,177.53 kB 1,188.31 kB +0.48% 258.84 kB 260.09 kB
facebook-www/ReactDOMForked-dev.classic.js +0.90% 1,201.14 kB 1,211.93 kB +0.47% 263.32 kB 264.57 kB
facebook-www/ReactDOM-dev.classic.js +0.90% 1,201.14 kB 1,211.93 kB +0.47% 263.33 kB 264.57 kB
oss-experimental/react-art/umd/react-art.production.min.js +0.83% 123.39 kB 124.42 kB +0.60% 38.37 kB 38.60 kB
oss-stable-semver/react-art/cjs/react-art.production.min.js +0.82% 82.79 kB 83.47 kB +0.70% 25.78 kB 25.96 kB
oss-stable/react-art/cjs/react-art.production.min.js +0.82% 82.81 kB 83.49 kB +0.70% 25.78 kB 25.96 kB
oss-stable-semver/react-test-renderer/cjs/react-test-renderer.production.min.js +0.76% 90.06 kB 90.74 kB +0.65% 27.88 kB 28.06 kB
oss-stable/react-test-renderer/cjs/react-test-renderer.production.min.js +0.76% 90.08 kB 90.76 kB +0.65% 27.88 kB 28.06 kB
oss-stable-semver/react-test-renderer/umd/react-test-renderer.production.min.js +0.75% 90.31 kB 90.99 kB +0.65% 28.27 kB 28.46 kB
oss-stable/react-test-renderer/umd/react-test-renderer.production.min.js +0.75% 90.34 kB 91.01 kB +0.65% 28.27 kB 28.46 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js +0.74% 138.15 kB 139.17 kB +0.59% 44.19 kB 44.45 kB
oss-experimental/react-dom/umd/react-dom.production.min.js +0.74% 138.20 kB 139.22 kB +0.51% 44.86 kB 45.09 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler.production.min.js +0.72% 94.11 kB 94.79 kB +0.65% 28.97 kB 29.16 kB
oss-stable/react-reconciler/cjs/react-reconciler.production.min.js +0.72% 94.14 kB 94.82 kB +0.66% 28.99 kB 29.18 kB
oss-experimental/react-dom/cjs/react-dom-unstable_testing.production.min.js +0.72% 143.41 kB 144.43 kB +0.59% 46.24 kB 46.51 kB
oss-stable-semver/react-dom/cjs/react-dom.development.js +0.71% 1,040.89 kB 1,048.26 kB +0.43% 233.35 kB 234.35 kB
oss-stable/react-dom/cjs/react-dom.development.js +0.71% 1,040.91 kB 1,048.29 kB +0.43% 233.38 kB 234.37 kB
oss-stable-semver/react-dom/umd/react-dom.development.js +0.70% 1,091.92 kB 1,099.59 kB +0.40% 235.99 kB 236.93 kB
oss-stable/react-dom/umd/react-dom.development.js +0.70% 1,091.94 kB 1,099.61 kB +0.40% 236.02 kB 236.95 kB
oss-experimental/react-dom/umd/react-dom.profiling.min.js +0.70% 147.06 kB 148.08 kB +0.56% 47.10 kB 47.36 kB
oss-experimental/react-dom/cjs/react-dom.profiling.min.js +0.69% 147.68 kB 148.70 kB +0.57% 46.62 kB 46.89 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler.profiling.min.js +0.65% 103.00 kB 103.67 kB +0.56% 31.24 kB 31.41 kB
oss-stable/react-reconciler/cjs/react-reconciler.profiling.min.js +0.65% 103.02 kB 103.69 kB +0.56% 31.26 kB 31.43 kB
oss-stable-semver/react-art/umd/react-art.production.min.js +0.57% 118.67 kB 119.34 kB +0.46% 37.02 kB 37.19 kB
oss-stable/react-art/umd/react-art.production.min.js +0.57% 118.69 kB 119.37 kB +0.46% 37.02 kB 37.19 kB
oss-stable-semver/react-dom/cjs/react-dom.production.min.js +0.51% 132.90 kB 133.58 kB +0.35% 42.68 kB 42.83 kB
oss-stable/react-dom/cjs/react-dom.production.min.js +0.51% 132.92 kB 133.60 kB +0.35% 42.68 kB 42.83 kB
oss-stable-semver/react-dom/umd/react-dom.production.min.js +0.51% 133.02 kB 133.69 kB +0.33% 43.34 kB 43.48 kB
oss-stable/react-dom/umd/react-dom.production.min.js +0.51% 133.04 kB 133.72 kB +0.33% 43.34 kB 43.48 kB
oss-stable-semver/react-dom/cjs/react-dom.profiling.min.js +0.47% 142.44 kB 143.11 kB +0.23% 45.17 kB 45.28 kB
oss-stable/react-dom/cjs/react-dom.profiling.min.js +0.47% 142.46 kB 143.13 kB +0.23% 45.17 kB 45.28 kB
oss-stable-semver/react-dom/umd/react-dom.profiling.min.js +0.47% 141.89 kB 142.55 kB +0.36% 45.60 kB 45.77 kB
oss-stable/react-dom/umd/react-dom.profiling.min.js +0.47% 141.91 kB 142.58 kB +0.36% 45.60 kB 45.77 kB

Generated by 🚫 dangerJS against e6a705b

@acdlite acdlite force-pushed the dont-mount-passive-during-prerendering branch from f162769 to 42a484e Compare July 21, 2022 04:42
acdlite added 4 commits July 22, 2022 00:41
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.
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.
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.
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.
@acdlite acdlite merged commit 4ea064e into facebook:main Jul 29, 2022
facebook-github-bot pushed a commit to facebook/react-native that referenced this pull request Sep 8, 2022
Summary:
This sync includes the following changes:
- **[4ea064eb0](facebook/react@4ea064eb0 )**: Don't fire passive effects during initial mount of a hidden Offscreen tree ([#24967](facebook/react#24967)) //<Andrew Clark>//
- **[2c7dea736](facebook/react@2c7dea736 )**: Implement Offscreen in Fizz ([#24988](facebook/react#24988)) //<Andrew Clark>//
- **[49f8254d6](facebook/react@49f8254d6 )**: Bug fix for <App /> vs. <Counter /> ([#24972](facebook/react#24972)) //<davidrenne>//
- **[6b28bc9c5](facebook/react@6b28bc9c5 )**: test: Throw custom error instead of relying on runtime error ([#24946](facebook/react#24946)) //<Sebastian Silbermann>//
- **[9bd0dd4c1](facebook/react@9bd0dd4c1 )**: test(react-debug-tools): Improve coverage of currentDispatcher.current setter ([#24945](facebook/react#24945)) //<Sebastian Silbermann>//
- **[59bc52a16](facebook/react@59bc52a16 )**: Add 4.5.0 release to eslint rules CHANGELOG ([#24853](facebook/react#24853)) //<Sebastian Silbermann>//
- **[cfb6cfa25](facebook/react@cfb6cfa25 )**: Reused components commit with timing as new ones //<Andrew Clark>//
- **[679eea328](facebook/react@679eea328 )**: Extract layout effects to separate functions //<Andrew Clark>//
- **[41287d447](facebook/react@41287d447 )**: Use recursion to traverse during "reappear layout" phase //<Andrew Clark>//
- **[697702bf3](facebook/react@697702bf3 )**: Use recursion to traverse during "disappear layout" phase //<Andrew Clark>//
- **[02206099a](facebook/react@02206099a )**: Use recursion to traverse during passive unmount phase ([#24918](facebook/react#24918)) //<Andrew Clark>//
- **[f62949519](facebook/react@f62949519 )**: [Transition Tracing] Rename transitionCallbacks to unstable_transitionCallbacks  ([#24920](facebook/react#24920)) //<Luna Ruan>//
- **[7a4336c40](facebook/react@7a4336c40 )**: Use recursion to traverse during passive mount phase //<Andrew Clark>//
- **[bb1357b38](facebook/react@bb1357b38 )**: Wrap try-catch directly around each user function //<Andrew Clark>//
- **[de3c06984](facebook/react@de3c06984 )**: Move flag check into each switch case //<Andrew Clark>//
- **[f5916d15b](facebook/react@f5916d15b )**: [Transition Tracing][Code Cleanup] Delete Marker Name Change Tests ([#24908](facebook/react#24908)) //<Luna Ruan>//
- **[fa20b319f](facebook/react@fa20b319f )**: [Transition Tracing] Code Cleanup ([#24880](facebook/react#24880)) //<Luna Ruan>//
- **[5e8c1961c](facebook/react@5e8c1961c )**: [Transition Tracing] onMarkerProgress ([#24861](facebook/react#24861)) //<Luna Ruan>//
- **[b641d0209](facebook/react@b641d0209 )**: Use recursion to traverse during layout phase //<Andrew Clark>//
- **[a1b1e391e](facebook/react@a1b1e391e )**: Wrap try-catch directly around each user function //<Andrew Clark>//
- **[3df7e8f5d](facebook/react@3df7e8f5d )**: Move flag check into each switch case //<Andrew Clark>//
- **[b8c96b136](facebook/react@b8c96b136 )**: Move ref commit effects inside switch statement //<Andrew Clark>//
- **[e225fa43a](facebook/react@e225fa43a )**: [Transition Tracing] Don't call transition callbacks if no transition name specified ([#24887](facebook/react#24887)) //<Luna Ruan>//
- **[dd2d65227](facebook/react@dd2d65227 )**: [Transition Tracing] Tracing Marker Name Change in Update Warning ([#24873](facebook/react#24873)) //<Luna Ruan>//
- **[80208e769](facebook/react@80208e769 )**: [Transition Tracing] Add onTransitionProgress Callback ([#24833](facebook/react#24833)) //<Luna Ruan>//
- **[30eb267ab](facebook/react@30eb267ab )**: Land forked reconciler changes ([#24878](facebook/react#24878)) //<Andrew Clark>//
- **[5e4e2dae0](facebook/react@5e4e2dae0 )**: Defer setState callbacks until component is visible ([#24872](facebook/react#24872)) //<Andrew Clark>//
- **[8e35b5060](facebook/react@8e35b5060 )**: [Transition Tracing] Refactor Code to Remove OffscreeInstance TODOs ([#24855](facebook/react#24855)) //<Luna Ruan>//
- **[deab1263a](facebook/react@deab1263a )**: [Transition Tracing] Change Transition Type Passed Pending Transitions ([#24856](facebook/react#24856)) //<Luna Ruan>//
- **[82e9e9909](facebook/react@82e9e9909 )**: Suspending inside a hidden tree should not cause fallbacks to appear ([#24699](facebook/react#24699)) //<Andrew Clark>//

Changelog:
[General][Changed] - React Native sync for revisions c1f5884...4ea064e

jest_e2e[run_all_tests]

Reviewed By: philIip, NickGerleman

Differential Revision: D39305648

fbshipit-source-id: 627ead5035c77fbc902b306e17897e425ad7fb99
rickhanlonii pushed a commit that referenced this pull request Oct 6, 2022
… 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.
acdlite added a commit to acdlite/react that referenced this pull request Oct 6, 2022
In facebook#24967, I changed the behavior of Offscreen so that passive effects
are not fired when the tree is hidden. I accidentally applied this
behavior to the old LegacyHidden API, too, which is a deprecated
internal-only type that www has been using while they wait for Offscreen
to be ready.

This fixes LegacyHidden so that the effects do not get deferred, like
before. The new behavior still remains in the Offscreen API, which is
experimental and not currently in use in www.
poteto pushed a commit that referenced this pull request Oct 6, 2022
In #24967, I changed the behavior of Offscreen so that passive effects
are not fired when the tree is hidden. I accidentally applied this
behavior to the old LegacyHidden API, too, which is a deprecated
internal-only type that www has been using while they wait for Offscreen
to be ready.

This fixes LegacyHidden so that the effects do not get deferred, like
before. The new behavior still remains in the Offscreen API, which is
experimental and not currently in use in www.
acdlite added a commit to acdlite/react that referenced this pull request Oct 6, 2022
In facebook#24967, I changed the behavior of Offscreen so that passive effects
are not fired when the tree is hidden. I accidentally applied this
behavior to the old LegacyHidden API, too, which is a deprecated
internal-only type that www has been using while they wait for Offscreen
to be ready.

This fixes LegacyHidden so that the effects do not get deferred, like
before. The new behavior still remains in the Offscreen API, which is
experimental and not currently in use in www.
acdlite added a commit to acdlite/react that referenced this pull request Oct 6, 2022
In facebook#24967, I changed the behavior of Offscreen so that passive effects
are not fired when the tree is hidden. I accidentally applied this
behavior to the old LegacyHidden API, too, which is a deprecated
internal-only type that www has been using while they wait for Offscreen
to be ready.

This fixes LegacyHidden so that the effects do not get deferred, like
before. The new behavior still remains in the Offscreen API, which is
experimental and not currently in use in www.
acdlite added a commit that referenced this pull request Oct 6, 2022
In #24967, I changed the behavior of Offscreen so that passive effects
are not fired when the tree is hidden. I accidentally applied this
behavior to the old LegacyHidden API, too, which is a deprecated
internal-only type that www has been using while they wait for Offscreen
to be ready.

This fixes LegacyHidden so that the effects do not get deferred, like
before. The new behavior still remains in the Offscreen API, which is
experimental and not currently in use in www.
OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this pull request May 22, 2023
Summary:
This sync includes the following changes:
- **[4ea064eb0](facebook/react@4ea064eb0 )**: Don't fire passive effects during initial mount of a hidden Offscreen tree ([facebook#24967](facebook/react#24967)) //<Andrew Clark>//
- **[2c7dea736](facebook/react@2c7dea736 )**: Implement Offscreen in Fizz ([facebook#24988](facebook/react#24988)) //<Andrew Clark>//
- **[49f8254d6](facebook/react@49f8254d6 )**: Bug fix for <App /> vs. <Counter /> ([facebook#24972](facebook/react#24972)) //<davidrenne>//
- **[6b28bc9c5](facebook/react@6b28bc9c5 )**: test: Throw custom error instead of relying on runtime error ([facebook#24946](facebook/react#24946)) //<Sebastian Silbermann>//
- **[9bd0dd4c1](facebook/react@9bd0dd4c1 )**: test(react-debug-tools): Improve coverage of currentDispatcher.current setter ([facebook#24945](facebook/react#24945)) //<Sebastian Silbermann>//
- **[59bc52a16](facebook/react@59bc52a16 )**: Add 4.5.0 release to eslint rules CHANGELOG ([facebook#24853](facebook/react#24853)) //<Sebastian Silbermann>//
- **[cfb6cfa25](facebook/react@cfb6cfa25 )**: Reused components commit with timing as new ones //<Andrew Clark>//
- **[679eea328](facebook/react@679eea328 )**: Extract layout effects to separate functions //<Andrew Clark>//
- **[41287d447](facebook/react@41287d447 )**: Use recursion to traverse during "reappear layout" phase //<Andrew Clark>//
- **[697702bf3](facebook/react@697702bf3 )**: Use recursion to traverse during "disappear layout" phase //<Andrew Clark>//
- **[02206099a](facebook/react@02206099a )**: Use recursion to traverse during passive unmount phase ([facebook#24918](facebook/react#24918)) //<Andrew Clark>//
- **[f62949519](facebook/react@f62949519 )**: [Transition Tracing] Rename transitionCallbacks to unstable_transitionCallbacks  ([facebook#24920](facebook/react#24920)) //<Luna Ruan>//
- **[7a4336c40](facebook/react@7a4336c40 )**: Use recursion to traverse during passive mount phase //<Andrew Clark>//
- **[bb1357b38](facebook/react@bb1357b38 )**: Wrap try-catch directly around each user function //<Andrew Clark>//
- **[de3c06984](facebook/react@de3c06984 )**: Move flag check into each switch case //<Andrew Clark>//
- **[f5916d15b](facebook/react@f5916d15b )**: [Transition Tracing][Code Cleanup] Delete Marker Name Change Tests ([facebook#24908](facebook/react#24908)) //<Luna Ruan>//
- **[fa20b319f](facebook/react@fa20b319f )**: [Transition Tracing] Code Cleanup ([facebook#24880](facebook/react#24880)) //<Luna Ruan>//
- **[5e8c1961c](facebook/react@5e8c1961c )**: [Transition Tracing] onMarkerProgress ([facebook#24861](facebook/react#24861)) //<Luna Ruan>//
- **[b641d0209](facebook/react@b641d0209 )**: Use recursion to traverse during layout phase //<Andrew Clark>//
- **[a1b1e391e](facebook/react@a1b1e391e )**: Wrap try-catch directly around each user function //<Andrew Clark>//
- **[3df7e8f5d](facebook/react@3df7e8f5d )**: Move flag check into each switch case //<Andrew Clark>//
- **[b8c96b136](facebook/react@b8c96b136 )**: Move ref commit effects inside switch statement //<Andrew Clark>//
- **[e225fa43a](facebook/react@e225fa43a )**: [Transition Tracing] Don't call transition callbacks if no transition name specified ([facebook#24887](facebook/react#24887)) //<Luna Ruan>//
- **[dd2d65227](facebook/react@dd2d65227 )**: [Transition Tracing] Tracing Marker Name Change in Update Warning ([facebook#24873](facebook/react#24873)) //<Luna Ruan>//
- **[80208e769](facebook/react@80208e769 )**: [Transition Tracing] Add onTransitionProgress Callback ([facebook#24833](facebook/react#24833)) //<Luna Ruan>//
- **[30eb267ab](facebook/react@30eb267ab )**: Land forked reconciler changes ([facebook#24878](facebook/react#24878)) //<Andrew Clark>//
- **[5e4e2dae0](facebook/react@5e4e2dae0 )**: Defer setState callbacks until component is visible ([facebook#24872](facebook/react#24872)) //<Andrew Clark>//
- **[8e35b5060](facebook/react@8e35b5060 )**: [Transition Tracing] Refactor Code to Remove OffscreeInstance TODOs ([facebook#24855](facebook/react#24855)) //<Luna Ruan>//
- **[deab1263a](facebook/react@deab1263a )**: [Transition Tracing] Change Transition Type Passed Pending Transitions ([facebook#24856](facebook/react#24856)) //<Luna Ruan>//
- **[82e9e9909](facebook/react@82e9e9909 )**: Suspending inside a hidden tree should not cause fallbacks to appear ([facebook#24699](facebook/react#24699)) //<Andrew Clark>//

Changelog:
[General][Changed] - React Native sync for revisions c1f5884...4ea064e

jest_e2e[run_all_tests]

Reviewed By: philIip, NickGerleman

Differential Revision: D39305648

fbshipit-source-id: 627ead5035c77fbc902b306e17897e425ad7fb99
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants