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

Fix react-dom/server context leaks when render stream destroyed early #14706

Conversation

overlookmotel
Copy link
Contributor

Fix and test case for #14705.

Note: This makes .popProvider's provider argument optional. It's only used in dev mode anyway, but I'm not sure if this is the wrong thing to do. Please excuse me - I've never used Flow before.

@overlookmotel
Copy link
Contributor Author

overlookmotel commented Jan 27, 2019

2nd test added for #14705 (comment).

@overlookmotel overlookmotel changed the title Fix react-dom/server context memory retention Fix react-dom/server context leaks when render stream destroyed early Jan 28, 2019
@@ -776,6 +777,16 @@ class ReactDOMServerRenderer {
context[this.threadID] = previousValue;
}

clearProviders(): void {
while (this.contextIndex > -1) {
if (__DEV__) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you write the loop inline with minimal work it needs to do? For example reading previous value seems unnecessary except for the last one. This would also avoid the overloading you had to add to popProvider.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've pushed another commit which does as you request.

However, the previous value does need to be restored for each Provider, as each Context's current value is stored separately on each Context object.

Well, if there were several nested Providers for the same Context, then yes you could only restore just the last previous value. But I don't think this would be more performative, as clearProviders() would need to loop over the array twice - once to identify any repeated contexts, and then a 2nd time to restore whatever was the oldest previous value for each Context.

I think it's probably cheaper to redundantly write the value multiple times in these cases.

But if you want further changes, please just say so and I'll implement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

NB This leaves contextStack and contextValueStack unaltered, and so retaining memory. But I guess since the PartialRenderer instance has been destroyed, it will be dereferenced and garbage collected shortly anyway.

@overlookmotel overlookmotel force-pushed the fix-reactdom-server-context-memory-retention branch from 8088074 to 94f70f5 Compare February 14, 2019 08:32
@sizebot
Copy link

sizebot commented Feb 14, 2019

ReactDOM: size: 0.0%, gzip: -0.0%

Details of bundled changes.

Comparing: 08e9554...855cc27

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js 0.0% -0.0% 765.31 KB 765.31 KB 174.44 KB 174.44 KB UMD_DEV
react-dom.production.min.js 0.0% -0.0% 105.34 KB 105.34 KB 33.94 KB 33.94 KB UMD_PROD
react-dom.profiling.min.js 0.0% -0.0% 108.26 KB 108.26 KB 34.82 KB 34.82 KB UMD_PROFILING
react-dom.development.js 0.0% -0.0% 759.91 KB 759.91 KB 172.95 KB 172.94 KB NODE_DEV
react-dom.production.min.js 0.0% -0.0% 105.5 KB 105.5 KB 33.43 KB 33.43 KB NODE_PROD
react-dom.profiling.min.js 0.0% -0.0% 108.58 KB 108.58 KB 34.25 KB 34.25 KB NODE_PROFILING
ReactDOM-dev.js 0.0% -0.0% 782.88 KB 782.88 KB 174.18 KB 174.18 KB FB_WWW_DEV
react-dom-unstable-fire.development.js 0.0% -0.0% 765.65 KB 765.65 KB 174.59 KB 174.58 KB UMD_DEV
react-dom-unstable-fire.production.min.js 0.0% -0.0% 105.35 KB 105.35 KB 33.95 KB 33.95 KB UMD_PROD
react-dom-unstable-fire.profiling.min.js 0.0% -0.0% 108.27 KB 108.27 KB 34.83 KB 34.83 KB UMD_PROFILING
react-dom-unstable-fire.development.js 0.0% -0.0% 760.26 KB 760.26 KB 173.09 KB 173.08 KB NODE_DEV
react-dom-unstable-fire.production.min.js 0.0% -0.0% 105.52 KB 105.52 KB 33.44 KB 33.44 KB NODE_PROD
react-dom-unstable-fire.profiling.min.js 0.0% -0.0% 108.59 KB 108.59 KB 34.26 KB 34.26 KB NODE_PROFILING
ReactFire-dev.js 0.0% -0.0% 782.09 KB 782.09 KB 174.1 KB 174.1 KB FB_WWW_DEV
react-dom-test-utils.development.js 0.0% -0.0% 47.06 KB 47.06 KB 12.99 KB 12.99 KB UMD_DEV
react-dom-test-utils.production.min.js 0.0% 🔺+0.1% 10.27 KB 10.27 KB 3.8 KB 3.8 KB UMD_PROD
react-dom-test-utils.production.min.js 0.0% -0.0% 10.05 KB 10.05 KB 3.73 KB 3.73 KB NODE_PROD
react-dom-unstable-native-dependencies.production.min.js 0.0% -0.0% 11.01 KB 11.01 KB 3.81 KB 3.81 KB UMD_PROD
react-dom-unstable-native-dependencies.development.js 0.0% -0.0% 60.28 KB 60.28 KB 15.79 KB 15.79 KB NODE_DEV
react-dom-unstable-native-dependencies.production.min.js 0.0% -0.0% 10.75 KB 10.75 KB 3.71 KB 3.71 KB NODE_PROD
react-dom-server.browser.development.js +0.3% +0.2% 126.78 KB 127.18 KB 33.81 KB 33.88 KB UMD_DEV
react-dom-server.browser.production.min.js 🔺+0.8% 🔺+0.4% 18.69 KB 18.85 KB 7.19 KB 7.22 KB UMD_PROD
react-dom-server.browser.development.js +0.3% +0.2% 122.91 KB 123.31 KB 32.87 KB 32.94 KB NODE_DEV
react-dom-server.browser.production.min.js 🔺+0.8% 🔺+0.5% 18.62 KB 18.77 KB 7.17 KB 7.2 KB NODE_PROD
ReactDOMServer-dev.js +0.3% +0.2% 123.85 KB 124.25 KB 32.38 KB 32.45 KB FB_WWW_DEV
ReactDOMServer-prod.js 🔺+0.5% 🔺+0.5% 44.98 KB 45.22 KB 10.37 KB 10.42 KB FB_WWW_PROD
react-dom-server.node.development.js +0.3% +0.2% 124.97 KB 125.37 KB 33.41 KB 33.48 KB NODE_DEV
react-dom-server.node.production.min.js 🔺+0.8% 🔺+0.5% 19.49 KB 19.65 KB 7.48 KB 7.51 KB NODE_PROD
react-dom-unstable-fizz.browser.development.js 0.0% -0.1% 3.63 KB 3.63 KB 1.44 KB 1.44 KB UMD_DEV
react-dom-unstable-fizz.browser.production.min.js 0.0% -0.1% 1.21 KB 1.21 KB 707 B 706 B UMD_PROD
react-dom-unstable-fizz.browser.development.js 0.0% -0.1% 3.45 KB 3.45 KB 1.39 KB 1.39 KB NODE_DEV
react-dom-unstable-fizz.browser.production.min.js 0.0% -0.2% 1.05 KB 1.05 KB 638 B 637 B NODE_PROD
react-dom-unstable-fizz.node.development.js 0.0% -0.1% 3.7 KB 3.7 KB 1.42 KB 1.42 KB NODE_DEV
react-dom-unstable-fizz.node.production.min.js 0.0% -0.1% 1.1 KB 1.1 KB 668 B 667 B NODE_PROD

Generated by 🚫 dangerJS

Copy link
Collaborator

@gaearon gaearon 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 good. Thanks for fixing.

@gaearon gaearon merged commit ab7a67b into facebook:master Feb 14, 2019
@overlookmotel
Copy link
Contributor Author

Thank you!

@overlookmotel overlookmotel deleted the fix-reactdom-server-context-memory-retention branch February 14, 2019 20:08
acdlite pushed a commit to acdlite/react that referenced this pull request Feb 20, 2019
…facebook#14706)

* Fix react-dom/server context memory retention

* Test for pollution of later renders

* Inline loop

* More tests
Deraen added a commit to cljsjs/packages that referenced this pull request Mar 2, 2019
## 16.8.2 => 16.8.3

### React DOM

* Fix a bug that caused inputs to behave incorrectly in UMD builds. ([@gaearon](https://github.com/gaearon) in [#14914](facebook/react#14914))
* Fix a bug that caused render phase updates to be discarded. ([@gaearon](https://github.com/gaearon) in [#14852](facebook/react#14852))

### React DOM Server
* Unwind the context stack when a stream is destroyed without completing, to prevent incorrect values during a subsequent render. ([@overlookmotel](https://github.com/overlookmotel) in [#14706](facebook/react#14706))
Deraen added a commit to cljsjs/packages that referenced this pull request Mar 2, 2019
## 16.8.2 => 16.8.3

### React DOM

* Fix a bug that caused inputs to behave incorrectly in UMD builds. ([@gaearon](https://github.com/gaearon) in [#14914](facebook/react#14914))
* Fix a bug that caused render phase updates to be discarded. ([@gaearon](https://github.com/gaearon) in [#14852](facebook/react#14852))

### React DOM Server
* Unwind the context stack when a stream is destroyed without completing, to prevent incorrect values during a subsequent render. ([@overlookmotel](https://github.com/overlookmotel) in [#14706](facebook/react#14706))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants