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

Align StrictMode behaviour with production #25049

Merged
merged 12 commits into from
Aug 23, 2022
Merged

Conversation

sammy-SC
Copy link
Contributor

@sammy-SC sammy-SC commented Aug 5, 2022

Summary

PR changes behaviour of StrictMode to better align it what mount/unmount/mount would look like in production.
We change custom traversal function that was previously used for StrictMode to functions used in production.
This has following implications:

  • refs are now attached/detached/attached in StrictMode.
  • When <unstable_Offscreen /> is hidden, StrictMode doesn't double invoke effects. StrictMode will double invoke effects when <unstable_Offscreen /> becomes visible.

How did you test this change?

I've added tests for how <unstable_Offscreen /> should behave in and a test to verify refs are detached in StrictMode.

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Aug 5, 2022
@sammy-SC sammy-SC force-pushed the strict-mode-offscreen-fixes branch from e84f7d7 to 72473a6 Compare August 5, 2022 09:46
@sizebot
Copy link

sizebot commented Aug 5, 2022

Comparing: 32baab3...6b3de9f

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.02% 134.28 kB 134.31 kB +0.01% 42.93 kB 42.93 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js +0.02% 139.84 kB 139.86 kB +0.03% 44.55 kB 44.57 kB
facebook-www/ReactDOM-prod.classic.js = 474.44 kB 474.46 kB = 84.86 kB 84.87 kB
facebook-www/ReactDOM-prod.modern.js = 459.68 kB 459.70 kB = 82.62 kB 82.63 kB
facebook-www/ReactDOMForked-prod.classic.js = 474.44 kB 474.46 kB = 84.86 kB 84.87 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
facebook-www/ReactDOM-dev.classic.js = 1,217.86 kB 1,215.13 kB = 265.80 kB 265.53 kB
facebook-www/ReactDOMForked-dev.classic.js = 1,217.86 kB 1,215.13 kB = 265.80 kB 265.52 kB
facebook-www/ReactDOM-dev.modern.js = 1,194.24 kB 1,191.51 kB = 261.32 kB 261.02 kB
facebook-www/ReactDOMForked-dev.modern.js = 1,194.24 kB 1,191.51 kB = 261.32 kB 261.02 kB
oss-experimental/react-dom/cjs/react-dom.development.js = 1,087.26 kB 1,084.61 kB = 242.25 kB 242.00 kB
oss-experimental/react-dom/umd/react-dom.development.js = 1,140.49 kB 1,137.65 kB = 244.96 kB 244.70 kB
oss-stable/react-dom/cjs/react-dom.development.js = 1,054.39 kB 1,051.73 kB = 235.48 kB 235.21 kB
oss-stable-semver/react-dom/cjs/react-dom.development.js = 1,054.36 kB 1,051.70 kB = 235.45 kB 235.19 kB
oss-stable/react-dom/umd/react-dom.development.js = 1,106.03 kB 1,103.19 kB = 238.12 kB 237.87 kB
oss-stable-semver/react-dom/umd/react-dom.development.js = 1,106.00 kB 1,103.17 kB = 238.10 kB 237.84 kB
react-native/implementations/ReactNativeRenderer-dev.fb.js = 847.44 kB 844.84 kB = 182.57 kB 182.32 kB
react-native/implementations/ReactFabric-dev.fb.js = 837.80 kB 835.19 kB = 179.91 kB 179.68 kB
facebook-www/ReactART-dev.classic.js = 832.87 kB 830.14 kB = 175.53 kB 175.23 kB
oss-experimental/react-reconciler/cjs/react-reconciler.development.js = 805.04 kB 802.38 kB = 170.51 kB 170.27 kB
facebook-www/ReactART-dev.modern.js = 822.65 kB 819.92 kB = 173.39 kB 173.09 kB
oss-experimental/react-art/umd/react-art.development.js = 844.28 kB 841.44 kB = 176.67 kB 176.40 kB
oss-stable/react-reconciler/cjs/react-reconciler.development.js = 774.12 kB 771.47 kB = 164.30 kB 164.06 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler.development.js = 774.10 kB 771.44 kB = 164.28 kB 164.04 kB
oss-stable/react-art/umd/react-art.development.js = 812.17 kB 809.34 kB = 170.45 kB 170.21 kB
oss-stable-semver/react-art/umd/react-art.development.js = 812.15 kB 809.31 kB = 170.43 kB 170.19 kB
facebook-www/ReactTestRenderer-dev.classic.js = 745.49 kB 742.89 kB = 158.67 kB 158.43 kB
facebook-www/ReactTestRenderer-dev.modern.js = 745.49 kB 742.88 kB = 158.67 kB 158.43 kB
oss-experimental/react-art/cjs/react-art.development.js = 738.25 kB 735.59 kB = 158.50 kB 158.25 kB
oss-stable/react-art/cjs/react-art.development.js = 707.62 kB 704.96 kB = 152.26 kB 152.00 kB
oss-stable-semver/react-art/cjs/react-art.development.js = 707.60 kB 704.94 kB = 152.24 kB 151.98 kB

Generated by 🚫 dangerJS against 6b3de9f

@sammy-SC sammy-SC force-pushed the strict-mode-offscreen-fixes branch from 7aa28cb to b57ebbf Compare August 5, 2022 11:18
@sammy-SC sammy-SC force-pushed the strict-mode-offscreen-fixes branch 6 times, most recently from f89ad29 to 6f2c551 Compare August 11, 2022 10:09
@sammy-SC sammy-SC changed the title Add a failing test for Offscreen in StrictMode Align StrictMode behaviour with production Aug 11, 2022
@sammy-SC sammy-SC force-pushed the strict-mode-offscreen-fixes branch 6 times, most recently from 8280f85 to b7856ae Compare August 12, 2022 11:11
@sammy-SC sammy-SC marked this pull request as ready for review August 15, 2022 16:04
Copy link
Collaborator

@acdlite acdlite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I left a handful of factoring suggestions but nothing blocking.

packages/react-reconciler/src/ReactFiberCommitWork.new.js Outdated Show resolved Hide resolved
// TODO (StrictEffects) Should we set a marker on the root if it contains strict effects
// so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level.
// Maybe not a big deal since this is DEV only behavior.
let child = parentFiber.child;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should wrap this whole function in if (parentFiber.subtreeFlags & PlacementDEV). That way we can skip over any paths that don't include insertions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this breaks tests in experimental environment.

yarn test -r=experimental ReactOffscreenStrictMode-test.js

I'll merge PR as is and dig into this later since it is an optimisation.

packages/react-reconciler/src/ReactFiberWorkLoop.new.js Outdated Show resolved Hide resolved
invokePassiveEffectUnmountInDEV,
);
if (isInStrictMode) {
disappearLayoutEffects(fiber);
Copy link
Collaborator

@acdlite acdlite Aug 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Factoring nit: All of these successive if branches include a isInStrictMode check. You can factor that out:

if (isInStrictMode) {
  disappearLayoutEffects(...);
  reappearLayoutEfffects(...);
  disconnectPassiveEffect(...);
  reconnectPassiveEffects(...);
}

Also I don't think the setCurrentDebugFiberInDEV stuff is necessary anymore because disappearLayoutEffects et al already set it before they run the effects code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setCurrentDebugFiberInDEV is needed for DevTools. I'm not sure what the interaction between DevTools + React is in this case but DevTool tests start failing without it.

@sammy-SC sammy-SC merged commit 5d1ce65 into main Aug 23, 2022
@sammy-SC sammy-SC deleted the strict-mode-offscreen-fixes branch August 23, 2022 17:19
GrinZero added a commit to GrinZero/react that referenced this pull request Aug 31, 2022
* 'main' of ssh://github.com/GrinZero/react: (26 commits)
  [devtools][easy] Fix flow type (facebook#25147)
  Remove Symbol Polyfill (again) (facebook#25144)
  Remove ReactFiberFlags MountLayoutDev and MountPassiveDev (facebook#25091)
  experimental_use(promise) (facebook#25084)
  [Transition Tracing] onMarkerIncomplete - Tracing Marker/Suspense Boundary Deletions (facebook#24885)
  [Flight] Add support for Webpack Async Modules (facebook#25138)
  Fix typo: supportsMicrotask -> supportsMicrotasks (facebook#25142)
  Allow functions to be used as module references (facebook#25137)
  Test the node-register hooks in unit tests (facebook#25132)
  Return closestInstance in `getInspectorDataForViewAtPoint` (facebook#25118)
  [DevTools] Highlight RN elements on hover (facebook#25106)
  Update fixtures/flight to webpack 5 (facebook#25115)
  Align StrictMode behaviour with production (facebook#25049)
  Scaffolding for useMemoCache hook (facebook#25123)
  devtools: Fix typo from directores to directories (facebook#25124)
  fixture: Fix typo from perfomrance to performance (facebook#25100)
  [DevTools] Add events necessary for click to inspect on RN (facebook#25111)
  Add missing createServerContext for experimental shared subset (facebook#25114)
  support subresource integrity for bootstrapScripts and bootstrapModules (facebook#25104)
  make preamble and postamble types explicit and fix typo (facebook#25102)
  ...
facebook-github-bot pushed a commit to facebook/react-native that referenced this pull request Sep 12, 2022
Summary:
This sync includes the following changes:
- **[c28f313e6](facebook/react@c28f313e6 )**: experimental_use(promise) for SSR ([#25214](facebook/react#25214)) //<Andrew Clark>//
- **[d6f9628a8](facebook/react@d6f9628a8 )**: Remove some RSC subset entry points that were removed in the main entry point ([#25209](facebook/react#25209)) //<Sebastian Markbåge>//
- **[a473d08fc](facebook/react@a473d08fc )**: Update to Flow from 0.97 to 0.122 ([#25204](facebook/react#25204)) //<Jan Kassens>//
- **[7028ce745](facebook/react@7028ce745 )**: experimental_use(promise) for Server Components ([#25207](facebook/react#25207)) //<Andrew Clark>//
- **[bfb65681e](facebook/react@bfb65681e )**: experimental_use(context)([#25202](facebook/react#25202)) //<mofeiZ>//
- **[f0efa1164](facebook/react@f0efa1164 )**: [flow] remove custom suppress comment config ([#25170](facebook/react#25170)) //<Jan Kassens>//
- **[2e7f422fe](facebook/react@2e7f422fe )**: Refactor: its type is Container ([#25153](facebook/react#25153)) //<bubucuo>//
- **[2c2d9a1df](facebook/react@2c2d9a1df )**: [eslint-plugin-react-hooks] only allow capitalized component names ([#25162](facebook/react#25162)) //<Jan Kassens>//
- **[36c908a6c](facebook/react@36c908a6c )**: Don't use the Flight terminology in public error messages ([#25166](facebook/react#25166)) //<Sebastian Markbåge>//
- **[8d1b057ec](facebook/react@8d1b057ec )**: [Flight] Minor error handling fixes ([#25151](facebook/react#25151)) //<Sebastian Markbåge>//
- **[9ff738f53](facebook/react@9ff738f53 )**: [devtools][easy] Fix flow type ([#25147](facebook/react#25147)) //<Tianyu Yao>//
- **[0de3ddf56](facebook/react@0de3ddf56 )**: Remove Symbol Polyfill (again) ([#25144](facebook/react#25144)) //<Ricky>//
- **[b36f72235](facebook/react@b36f72235 )**: Remove ReactFiberFlags MountLayoutDev and MountPassiveDev ([#25091](facebook/react#25091)) //<Samuel Susla>//
- **[b6978bc38](facebook/react@b6978bc38 )**: experimental_use(promise) ([#25084](facebook/react#25084)) //<Andrew Clark>//
- **[11ed7010c](facebook/react@11ed7010c )**: [Transition Tracing] onMarkerIncomplete - Tracing Marker/Suspense Boundary Deletions ([#24885](facebook/react#24885)) //<Luna Ruan>//
- **[b79894259](facebook/react@b79894259 )**: [Flight] Add support for Webpack Async Modules ([#25138](facebook/react#25138)) //<Sebastian Markbåge>//
- **[c8b778b7f](facebook/react@c8b778b7f )**: Fix typo: supportsMicrotask -> supportsMicrotasks ([#25142](facebook/react#25142)) //<kwzr>//
- **[d0f396651](facebook/react@d0f396651 )**: Allow functions to be used as module references ([#25137](facebook/react#25137)) //<Sebastian Markbåge>//
- **[38c5d8a03](facebook/react@38c5d8a03 )**: Test the node-register hooks in unit tests ([#25132](facebook/react#25132)) //<Sebastian Markbåge>//
- **[3f70e68ce](facebook/react@3f70e68ce )**: Return closestInstance in `getInspectorDataForViewAtPoint` ([#25118](facebook/react#25118)) //<Tianyu Yao>//
- **[3d443cad7](facebook/react@3d443cad7 )**: Update fixtures/flight to webpack 5 ([#25115](facebook/react#25115)) //<Tim Neutkens>//
- **[5d1ce6513](facebook/react@5d1ce6513 )**: Align StrictMode behaviour with production ([#25049](facebook/react#25049)) //<Samuel Susla>//
- **[9e67e7a31](facebook/react@9e67e7a31 )**: Scaffolding for useMemoCache hook ([#25123](facebook/react#25123)) //<Joseph Savona>//
- **[19e9a4c68](facebook/react@19e9a4c68 )**: Add missing createServerContext for experimental shared subset ([#25114](facebook/react#25114)) //<Jiachi Liu>//
- **[6ef466c68](facebook/react@6ef466c68 )**: make preamble and postamble types explicit and fix typo ([#25102](facebook/react#25102)) //<Josh Story>//
- **[796d31809](facebook/react@796d31809 )**: Implement basic stylesheet Resources for react-dom ([#25060](facebook/react#25060)) //<Josh Story>//
- **[32baab38f](facebook/react@32baab38f )**: [Transition Tracing] Add Tag Field to Marker Instance ([#25085](facebook/react#25085)) //<Luna Ruan>//
- **[8ef3a7c08](facebook/react@8ef3a7c08 )**: Resume immediately pinged fiber without unwinding ([#25074](facebook/react#25074)) //<Andrew Clark>//
- **[7bcc68772](facebook/react@7bcc68772 )**: Remove argument committedLanes from reappearLayoutEffects and recursivelyTraverseReappearLayoutEffects ([#25080](facebook/react#25080)) //<Samuel Susla>//
- **[ca990e9a7](facebook/react@ca990e9a7 )**: Add API to force Scheduler to yield for macrotask ([#25044](facebook/react#25044)) //<Andrew Clark>//
- **[b4204ede6](facebook/react@b4204ede6 )**: Clean up unused Deletion flag ([#24992](facebook/react#24992)) //<Andrew Clark>//
- **[e193be87e](facebook/react@e193be87e )**: [Transition Tracing] Add Offscreen Test ([#25035](facebook/react#25035)) //<Luna Ruan>//
- **[9fcaf88d5](facebook/react@9fcaf88d5 )**: Remove rootContainerInstance from unnecessary places ([#25024](facebook/react#25024)) //<Sebastian Markbåge>//
- **[80f3d8819](facebook/react@80f3d8819 )**: Mount/unmount passive effects when Offscreen visibility changes ([#24977](facebook/react#24977)) //<Andrew Clark>//

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

Reviewed By: rickhanlonii

Differential Revision: D39384898

fbshipit-source-id: 20b080a53851d6dd9d522c8468dd02aab9ba76db
rickhanlonii pushed a commit that referenced this pull request Oct 5, 2022
* Skip double invoking effects in Offscreen

* Run yarn replace-fork

* Use executionContext to disable profiler timer

* Restructure recursion into two functions

* Fix ReactStrictMode test

* Use gate pragma in ReacetOffscreenStrictMode test

* Set and reset current debug fiber in dev

* Skip over paths that don't include any insertions

* Extract common logic to check for profiling to a helper function

* Remove hasPassiveEffects flag from StrictMode

* Fix flow issues

* Revert "Skip over paths that don't include any insertions"
OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this pull request May 22, 2023
Summary:
This sync includes the following changes:
- **[c28f313e6](facebook/react@c28f313e6 )**: experimental_use(promise) for SSR ([facebook#25214](facebook/react#25214)) //<Andrew Clark>//
- **[d6f9628a8](facebook/react@d6f9628a8 )**: Remove some RSC subset entry points that were removed in the main entry point ([facebook#25209](facebook/react#25209)) //<Sebastian Markbåge>//
- **[a473d08fc](facebook/react@a473d08fc )**: Update to Flow from 0.97 to 0.122 ([facebook#25204](facebook/react#25204)) //<Jan Kassens>//
- **[7028ce745](facebook/react@7028ce745 )**: experimental_use(promise) for Server Components ([facebook#25207](facebook/react#25207)) //<Andrew Clark>//
- **[bfb65681e](facebook/react@bfb65681e )**: experimental_use(context)([facebook#25202](facebook/react#25202)) //<mofeiZ>//
- **[f0efa1164](facebook/react@f0efa1164 )**: [flow] remove custom suppress comment config ([facebook#25170](facebook/react#25170)) //<Jan Kassens>//
- **[2e7f422fe](facebook/react@2e7f422fe )**: Refactor: its type is Container ([facebook#25153](facebook/react#25153)) //<bubucuo>//
- **[2c2d9a1df](facebook/react@2c2d9a1df )**: [eslint-plugin-react-hooks] only allow capitalized component names ([facebook#25162](facebook/react#25162)) //<Jan Kassens>//
- **[36c908a6c](facebook/react@36c908a6c )**: Don't use the Flight terminology in public error messages ([facebook#25166](facebook/react#25166)) //<Sebastian Markbåge>//
- **[8d1b057ec](facebook/react@8d1b057ec )**: [Flight] Minor error handling fixes ([facebook#25151](facebook/react#25151)) //<Sebastian Markbåge>//
- **[9ff738f53](facebook/react@9ff738f53 )**: [devtools][easy] Fix flow type ([facebook#25147](facebook/react#25147)) //<Tianyu Yao>//
- **[0de3ddf56](facebook/react@0de3ddf56 )**: Remove Symbol Polyfill (again) ([facebook#25144](facebook/react#25144)) //<Ricky>//
- **[b36f72235](facebook/react@b36f72235 )**: Remove ReactFiberFlags MountLayoutDev and MountPassiveDev ([facebook#25091](facebook/react#25091)) //<Samuel Susla>//
- **[b6978bc38](facebook/react@b6978bc38 )**: experimental_use(promise) ([facebook#25084](facebook/react#25084)) //<Andrew Clark>//
- **[11ed7010c](facebook/react@11ed7010c )**: [Transition Tracing] onMarkerIncomplete - Tracing Marker/Suspense Boundary Deletions ([facebook#24885](facebook/react#24885)) //<Luna Ruan>//
- **[b79894259](facebook/react@b79894259 )**: [Flight] Add support for Webpack Async Modules ([facebook#25138](facebook/react#25138)) //<Sebastian Markbåge>//
- **[c8b778b7f](facebook/react@c8b778b7f )**: Fix typo: supportsMicrotask -> supportsMicrotasks ([facebook#25142](facebook/react#25142)) //<kwzr>//
- **[d0f396651](facebook/react@d0f396651 )**: Allow functions to be used as module references ([facebook#25137](facebook/react#25137)) //<Sebastian Markbåge>//
- **[38c5d8a03](facebook/react@38c5d8a03 )**: Test the node-register hooks in unit tests ([facebook#25132](facebook/react#25132)) //<Sebastian Markbåge>//
- **[3f70e68ce](facebook/react@3f70e68ce )**: Return closestInstance in `getInspectorDataForViewAtPoint` ([facebook#25118](facebook/react#25118)) //<Tianyu Yao>//
- **[3d443cad7](facebook/react@3d443cad7 )**: Update fixtures/flight to webpack 5 ([facebook#25115](facebook/react#25115)) //<Tim Neutkens>//
- **[5d1ce6513](facebook/react@5d1ce6513 )**: Align StrictMode behaviour with production ([facebook#25049](facebook/react#25049)) //<Samuel Susla>//
- **[9e67e7a31](facebook/react@9e67e7a31 )**: Scaffolding for useMemoCache hook ([facebook#25123](facebook/react#25123)) //<Joseph Savona>//
- **[19e9a4c68](facebook/react@19e9a4c68 )**: Add missing createServerContext for experimental shared subset ([facebook#25114](facebook/react#25114)) //<Jiachi Liu>//
- **[6ef466c68](facebook/react@6ef466c68 )**: make preamble and postamble types explicit and fix typo ([facebook#25102](facebook/react#25102)) //<Josh Story>//
- **[796d31809](facebook/react@796d31809 )**: Implement basic stylesheet Resources for react-dom ([facebook#25060](facebook/react#25060)) //<Josh Story>//
- **[32baab38f](facebook/react@32baab38f )**: [Transition Tracing] Add Tag Field to Marker Instance ([facebook#25085](facebook/react#25085)) //<Luna Ruan>//
- **[8ef3a7c08](facebook/react@8ef3a7c08 )**: Resume immediately pinged fiber without unwinding ([facebook#25074](facebook/react#25074)) //<Andrew Clark>//
- **[7bcc68772](facebook/react@7bcc68772 )**: Remove argument committedLanes from reappearLayoutEffects and recursivelyTraverseReappearLayoutEffects ([facebook#25080](facebook/react#25080)) //<Samuel Susla>//
- **[ca990e9a7](facebook/react@ca990e9a7 )**: Add API to force Scheduler to yield for macrotask ([facebook#25044](facebook/react#25044)) //<Andrew Clark>//
- **[b4204ede6](facebook/react@b4204ede6 )**: Clean up unused Deletion flag ([facebook#24992](facebook/react#24992)) //<Andrew Clark>//
- **[e193be87e](facebook/react@e193be87e )**: [Transition Tracing] Add Offscreen Test ([facebook#25035](facebook/react#25035)) //<Luna Ruan>//
- **[9fcaf88d5](facebook/react@9fcaf88d5 )**: Remove rootContainerInstance from unnecessary places ([facebook#25024](facebook/react#25024)) //<Sebastian Markbåge>//
- **[80f3d8819](facebook/react@80f3d8819 )**: Mount/unmount passive effects when Offscreen visibility changes ([facebook#24977](facebook/react#24977)) //<Andrew Clark>//

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

Reviewed By: rickhanlonii

Differential Revision: D39384898

fbshipit-source-id: 20b080a53851d6dd9d522c8468dd02aab9ba76db
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.

4 participants