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 recreate the same fallback on the client if hydrating suspends #24236

Merged
merged 5 commits into from
Apr 1, 2022

Conversation

gaearon
Copy link
Collaborator

@gaearon gaearon commented Mar 31, 2022

If the server errors (or if it suspends in renderToString, which is like erroring — there's never gonna be more content) within a Suspense boundary, we send its fallback to the client with a special marker. The client is supposed to retry rendering that Suspense boundary's content during hydration with a clean render and replace the DOM.

The question is what happens if hydrating suspends. Previously, we'd use the result of that clean render. However, the result is the same fallback. So we'd just replace a server fallback with the same client fallback. This would thrash the DOM, restart animations, etc. Since there is no reason to do this, in this PR, we instead throw away the commit and leave the server fallback in place. Then, when we're able to render the content, we commit that clean render and report the server error.

If there is another root update though, fallback props could've changed. E.g. theme switch. In that case we recreate it. (Unless it is a transition — that's not urgent, so it can wait.)

This fixes the case originally discovered in #24229. I've also added new tests just for this case.

@facebook-github-bot facebook-github-bot added the React Core Team Opened by a member of the React Core Team label Mar 31, 2022
@sizebot
Copy link

sizebot commented Mar 31, 2022

Comparing: 4db3ff6...6cb9f18

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 = 131.30 kB 131.30 kB +0.03% 41.96 kB 41.97 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js = 136.36 kB 136.36 kB +0.01% 43.41 kB 43.42 kB
facebook-www/ReactDOM-prod.classic.js = 432.72 kB 432.75 kB = 79.59 kB 79.58 kB
facebook-www/ReactDOM-prod.modern.js = 417.72 kB 417.75 kB = 77.21 kB 77.21 kB
facebook-www/ReactDOMForked-prod.classic.js = 432.72 kB 432.75 kB = 79.59 kB 79.58 kB

Significant size changes

Includes any change greater than 0.2%:

(No significant changes)

Generated by 🚫 dangerJS against 6cb9f18

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 makes sense to me. I'm a little suspicious of the renderDidSuspendDelayIfPossible call but there's already a known problem related to that, so I can take a look when I work on that fix.

@gaearon
Copy link
Collaborator Author

gaearon commented Mar 31, 2022

Let's get Seb to look at the changed tests since this call was his idea

Copy link
Collaborator

@sebmarkbage sebmarkbage left a comment

Choose a reason for hiding this comment

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

It would be nice to have a test that tests just the simple case. The server errors, the client is suspends but no errors. The fallback doesn’t get replaced. The it unsuspends.

With the rationale spelled out that we don’t want to interrupt animations in the fallback.

@gaearon
Copy link
Collaborator Author

gaearon commented Mar 31, 2022

OK so I'll add tests for:

  1. Server errors, client doesn't but suspends. Client doesn't remount fallback because that would be silly.
  2. Server errors, client doesn't but suspends. Then new prop update making fallback a different color. Client remounts.

Sounds right @sebmarkbage ?

@gaearon gaearon changed the title Delay showing fallback if hydrating suspends Don't recreate the same fallback on the client if hydrating suspends Apr 1, 2022
@gaearon gaearon merged commit ebd7ff6 into facebook:main Apr 1, 2022
@gaearon gaearon deleted the delay-fallback-hydration branch April 1, 2022 01:50
facebook-github-bot pushed a commit to facebook/react-native that referenced this pull request Apr 12, 2022
Summary:
This sync includes the following changes:
- **[e8f4a6653](facebook/react@e8f4a6653 )**: Fix import in example //<dan>//
- **[bb49abea2](facebook/react@bb49abea2 )**: Update some READMEs ([#24290](facebook/react#24290)) //<dan>//
- **[4bc465a16](facebook/react@4bc465a16 )**: Rename Controls to PipeableStream ([#24286](facebook/react#24286)) //<Sebastian Markbåge>//
- **[ece5295e5](facebook/react@ece5295e5 )**: Remove unnecessary flag check ([#24284](facebook/react#24284)) //<zhoulixiang>//
- **[9ededef94](facebook/react@9ededef94 )**: Don't mute hydration errors forcing client render ([#24276](facebook/react#24276)) //<dan>//
- **[985272e26](facebook/react@985272e26 )**: Fix name mismatch in react-reconciler custom build. ([#24272](facebook/react#24272)) //<Hikari Hayashi>//
- **[b8cfda15e](facebook/react@b8cfda15e )**: changed Transitions type to Array<Transition> ([#24249](facebook/react#24249)) //<Luna Ruan>//
- **[c89a15c71](facebook/react@c89a15c71 )**: [ReactDebugTools] wrap uncaught error from rendering user's component ([#24216](facebook/react#24216)) //<Mengdi "Monday" Chen>//
- **[ebd7ff65b](facebook/react@ebd7ff65b )**: Don't recreate the same fallback on the client if hydrating suspends ([#24236](facebook/react#24236)) //<dan>//
- **[aa05e7315](facebook/react@aa05e7315 )**: Add 4.4.0 release to eslint rules CHANGELOG ([#24234](facebook/react#24234)) //<Brian Vaughn>//
- **[7e3121e1c](facebook/react@7e3121e1c )**: Remove unstable_createMutableSource from experimental build ([#24209](facebook/react#24209)) //<Sebastian Silbermann>//
- **[0415b18a1](facebook/react@0415b18a1 )**: [ReactDebugTools] add custom error type for future new hooks ([#24168](facebook/react#24168)) //<Mengdi "Monday" Chen>//

Changelog:
[General][Changed] - React Native sync for revisions 34aa5cf...e8f4a66

jest_e2e[run_all_tests]

Reviewed By: kacieb

Differential Revision: D35581059

fbshipit-source-id: ee031dfc49b1ef663b601f33f3f3f6c5a804971e
rickhanlonii pushed a commit that referenced this pull request Apr 13, 2022
…24236)

* Delay showing fallback if hydrating suspends

* Fix up

* Include all non-urgent lanes

* Moar tests

* Add test for transitions
rickhanlonii pushed a commit that referenced this pull request Apr 14, 2022
…24236)

* Delay showing fallback if hydrating suspends

* Fix up

* Include all non-urgent lanes

* Moar tests

* Add test for transitions
rickhanlonii pushed a commit that referenced this pull request Apr 14, 2022
…24236)

* Delay showing fallback if hydrating suspends

* Fix up

* Include all non-urgent lanes

* Moar tests

* Add test for transitions
zhengjitf pushed a commit to zhengjitf/react that referenced this pull request Apr 15, 2022
…acebook#24236)

* Delay showing fallback if hydrating suspends

* Fix up

* Include all non-urgent lanes

* Moar tests

* Add test for transitions
gaearon added a commit to gaearon/react that referenced this pull request Apr 25, 2022
gaearon added a commit to gaearon/react that referenced this pull request Apr 25, 2022
@gaearon
Copy link
Collaborator Author

gaearon commented Apr 25, 2022

I reverted this in #24434.

gaearon added a commit that referenced this pull request Apr 25, 2022
…ating suspends) (#24434)

* Revert #24236 (Don't recreate the same fallback on the client if hydrating suspends)

* Use @GATE FIXME
Saadnajmi pushed a commit to Saadnajmi/react-native-macos that referenced this pull request Jan 15, 2023
Summary:
This sync includes the following changes:
- **[e8f4a6653](facebook/react@e8f4a6653 )**: Fix import in example //<dan>//
- **[bb49abea2](facebook/react@bb49abea2 )**: Update some READMEs ([facebook#24290](facebook/react#24290)) //<dan>//
- **[4bc465a16](facebook/react@4bc465a16 )**: Rename Controls to PipeableStream ([facebook#24286](facebook/react#24286)) //<Sebastian Markbåge>//
- **[ece5295e5](facebook/react@ece5295e5 )**: Remove unnecessary flag check ([facebook#24284](facebook/react#24284)) //<zhoulixiang>//
- **[9ededef94](facebook/react@9ededef94 )**: Don't mute hydration errors forcing client render ([facebook#24276](facebook/react#24276)) //<dan>//
- **[985272e26](facebook/react@985272e26 )**: Fix name mismatch in react-reconciler custom build. ([facebook#24272](facebook/react#24272)) //<Hikari Hayashi>//
- **[b8cfda15e](facebook/react@b8cfda15e )**: changed Transitions type to Array<Transition> ([facebook#24249](facebook/react#24249)) //<Luna Ruan>//
- **[c89a15c71](facebook/react@c89a15c71 )**: [ReactDebugTools] wrap uncaught error from rendering user's component ([facebook#24216](facebook/react#24216)) //<Mengdi "Monday" Chen>//
- **[ebd7ff65b](facebook/react@ebd7ff65b )**: Don't recreate the same fallback on the client if hydrating suspends ([facebook#24236](facebook/react#24236)) //<dan>//
- **[aa05e7315](facebook/react@aa05e7315 )**: Add 4.4.0 release to eslint rules CHANGELOG ([facebook#24234](facebook/react#24234)) //<Brian Vaughn>//
- **[7e3121e1c](facebook/react@7e3121e1c )**: Remove unstable_createMutableSource from experimental build ([facebook#24209](facebook/react#24209)) //<Sebastian Silbermann>//
- **[0415b18a1](facebook/react@0415b18a1 )**: [ReactDebugTools] add custom error type for future new hooks ([facebook#24168](facebook/react#24168)) //<Mengdi "Monday" Chen>//

Changelog:
[General][Changed] - React Native sync for revisions 34aa5cf...e8f4a66

jest_e2e[run_all_tests]

Reviewed By: kacieb

Differential Revision: D35581059

fbshipit-source-id: ee031dfc49b1ef663b601f33f3f3f6c5a804971e
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