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

[react-interactions] Move Flare event registration to commit phase #17518

Merged
merged 1 commit into from
Dec 4, 2019

Conversation

trueadm
Copy link
Contributor

@trueadm trueadm commented Dec 4, 2019

This PR fixes an issue that can lead to memory leaks with the Flare event system. Specifically, the Flare event system has the notion of "root events" that are meant to be triggered when an incoming dispatched event gets bubbled to the document. Upon hitting the document, we then check a global Map, to see if there are any active event responders listening to the given type of event coming through.

The issue is that this Map can't be GC'd when DOM nodes are detached and removed, because we need to iterate over the Map's values to get all active responders that listen to root events. Normally, this wouldn't be an issue, but because of the heuristics as to how React reconciles responders differently depending on initial render vs update render, the root events can be subscribed to, but never used due to unwinding and other characteristics within the reconciliation processes. The expectation is that things that occur in initial render should be effects that can be unwound simply due to the nature of the garbage collector, but because of the nature of how root events work – this will never be the case (we need to be able to iterate over root events on any given incoming dispatch event, which means we can't use a WeakMap or WeakSet).

In the ideal world, no root event listeners should be created on initial render. Unfortunately, this is likely to be a more complex and feature breaking change to make at this point given the requirements of the Focus and FocusWithin event responders, which both make use of root events on initial mount. This PR tackles the problem in a somewhat brute-force approach, by moving all React Flare responders to the commit phase, at the compromise of more commit phase work vs the benefit of no leaking of the root event Map.

I believe this is probably the best short-term solution, and a lesson we can take forward in ironing out kinks with the newer Listener API. We can also, in the short-term, possibly come up with a way of remove root events from event responders on initial mount and finding a way to make them work conditionally, but this will likely take a larger period of time. In the interests of unblocking this memory leak, this seems the most sane path forward at this point.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Dec 4, 2019

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit c8794a0:

Sandbox Source
sparkling-monad-byt65 Configuration

@sizebot
Copy link

sizebot commented Dec 4, 2019

Details of bundled changes.

Comparing: 54f6673...c8794a0

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactFabric-prod.js 0.0% -0.0% 268.98 KB 268.98 KB 46.11 KB 46.11 KB RN_FB_PROD
ReactNativeRenderer-dev.js -0.0% -0.0% 749.64 KB 749.28 KB 158.66 KB 158.61 KB RN_OSS_DEV
ReactFabric-profiling.js 0.0% -0.0% 279.11 KB 279.11 KB 47.99 KB 47.99 KB RN_FB_PROFILING
ReactNativeRenderer-prod.js 0.0% -0.0% 277.32 KB 277.32 KB 47.55 KB 47.54 KB RN_FB_PROD
ReactFabric-dev.js -0.0% -0.0% 755.05 KB 754.69 KB 159.49 KB 159.44 KB RN_OSS_DEV
ReactFabric-prod.js 0.0% -0.0% 268.63 KB 268.63 KB 46.04 KB 46.04 KB RN_OSS_PROD
ReactFabric-profiling.js 0.0% -0.0% 278.76 KB 278.76 KB 47.92 KB 47.92 KB RN_OSS_PROFILING
ReactFabric-dev.js -0.0% -0.0% 755.24 KB 754.87 KB 159.57 KB 159.52 KB RN_FB_DEV
ReactNativeRenderer-dev.js -0.0% -0.0% 749.82 KB 749.45 KB 158.74 KB 158.69 KB RN_FB_DEV

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer.development.js -0.0% -0.0% 618.6 KB 618.42 KB 131.83 KB 131.79 KB UMD_DEV
react-test-renderer.production.min.js 0.0% -0.0% 71.65 KB 71.65 KB 21.95 KB 21.95 KB UMD_PROD
ReactTestRenderer-dev.js -0.1% -0.0% 629.37 KB 629.01 KB 131.02 KB 130.98 KB FB_WWW_DEV
react-test-renderer-shallow.development.js 0.0% -0.0% 39.11 KB 39.11 KB 10.01 KB 10.01 KB UMD_DEV
react-test-renderer-shallow.production.min.js 0.0% -0.0% 11.6 KB 11.6 KB 3.58 KB 3.58 KB UMD_PROD
react-test-renderer-shallow.development.js 0.0% -0.0% 33.07 KB 33.07 KB 8.54 KB 8.54 KB NODE_DEV
react-test-renderer-shallow.production.min.js 0.0% -0.0% 11.73 KB 11.73 KB 3.69 KB 3.69 KB NODE_PROD
react-test-renderer.development.js -0.0% -0.0% 613.87 KB 613.69 KB 130.64 KB 130.6 KB NODE_DEV

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactART-dev.js -0.1% -0.0% 617.7 KB 617.34 KB 128.45 KB 128.41 KB FB_WWW_DEV
ReactART-prod.js -0.3% -0.3% 236.13 KB 235.45 KB 39.79 KB 39.69 KB FB_WWW_PROD
react-art.development.js -0.0% -0.0% 673.69 KB 673.51 KB 146.13 KB 146.09 KB UMD_DEV
react-art.production.min.js 0.0% -0.0% 106.67 KB 106.67 KB 32.42 KB 32.42 KB UMD_PROD
react-art.development.js -0.0% -0.0% 604.33 KB 604.15 KB 128.74 KB 128.7 KB NODE_DEV

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom-server.browser.development.js 0.0% -0.0% 140.46 KB 140.46 KB 36.91 KB 36.91 KB UMD_DEV
react-dom-server.browser.production.min.js 0.0% -0.0% 20.39 KB 20.39 KB 7.48 KB 7.48 KB UMD_PROD
react-dom-unstable-fizz.browser.development.js 0.0% -0.1% 3.88 KB 3.88 KB 1.55 KB 1.55 KB UMD_DEV
react-dom-test-utils.production.min.js 0.0% -0.0% 11.18 KB 11.18 KB 4.15 KB 4.15 KB UMD_PROD
ReactDOMServer-dev.js 0.0% -0.0% 139.73 KB 139.73 KB 35.46 KB 35.46 KB FB_WWW_DEV
react-dom-test-utils.development.js 0.0% -0.0% 54.48 KB 54.48 KB 15.22 KB 15.22 KB NODE_DEV
ReactDOMServer-prod.js 0.0% -0.0% 48.91 KB 48.91 KB 11.18 KB 11.18 KB FB_WWW_PROD
react-dom-unstable-fizz.browser.development.js 0.0% -0.1% 3.71 KB 3.71 KB 1.5 KB 1.5 KB NODE_DEV
react-dom-test-utils.production.min.js 0.0% -0.0% 10.95 KB 10.95 KB 4.09 KB 4.09 KB NODE_PROD
react-dom.development.js -0.0% -0.0% 954.05 KB 953.88 KB 215.67 KB 215.63 KB UMD_DEV
react-dom.production.min.js 0.0% -0.0% 119.59 KB 119.59 KB 38.42 KB 38.42 KB UMD_PROD
react-dom.development.js -0.0% -0.0% 948.12 KB 947.94 KB 214.09 KB 214.05 KB NODE_DEV
react-dom.production.min.js 0.0% -0.0% 119.73 KB 119.73 KB 37.79 KB 37.79 KB NODE_PROD
react-dom-unstable-native-dependencies.development.js 0.0% -0.0% 60.14 KB 60.14 KB 15.8 KB 15.8 KB UMD_DEV
ReactDOM-dev.js -0.0% -0.0% 976.15 KB 975.79 KB 216.61 KB 216.57 KB FB_WWW_DEV
ReactDOM-prod.js -0.3% -0.6% 402.83 KB 401.54 KB 73.37 KB 72.89 KB FB_WWW_PROD
react-dom-unstable-native-dependencies.development.js 0.0% -0.0% 59.82 KB 59.82 KB 15.67 KB 15.66 KB NODE_DEV
ReactDOM-profiling.js -0.1% -0.1% 403.79 KB 403.4 KB 73.89 KB 73.83 KB FB_WWW_PROFILING

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

Size changes (experimental)

Generated by 🚫 dangerJS against c8794a0

@sizebot
Copy link

sizebot commented Dec 4, 2019

Details of bundled changes.

Comparing: 54f6673...c8794a0

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js -0.0% -0.0% 749.8 KB 749.44 KB 158.73 KB 158.69 KB RN_FB_DEV
ReactNativeRenderer-prod.js 0.0% -0.0% 277.31 KB 277.31 KB 47.54 KB 47.54 KB RN_FB_PROD
ReactFabric-dev.js -0.0% -0.0% 755.22 KB 754.86 KB 159.56 KB 159.51 KB RN_FB_DEV
ReactFabric-prod.js 0.0% -0.0% 268.96 KB 268.96 KB 46.1 KB 46.1 KB RN_FB_PROD
ReactFabric-profiling.js 0.0% -0.0% 279.1 KB 279.1 KB 47.98 KB 47.98 KB RN_FB_PROFILING
ReactNativeRenderer-dev.js -0.0% -0.0% 749.63 KB 749.27 KB 158.65 KB 158.6 KB RN_OSS_DEV
ReactFabric-dev.js -0.0% -0.0% 755.04 KB 754.68 KB 159.48 KB 159.43 KB RN_OSS_DEV
ReactFabric-prod.js 0.0% -0.0% 268.62 KB 268.62 KB 46.03 KB 46.03 KB RN_OSS_PROD
ReactFabric-profiling.js 0.0% -0.0% 278.75 KB 278.75 KB 47.91 KB 47.91 KB RN_OSS_PROFILING

Size changes (stable)

Generated by 🚫 dangerJS against c8794a0

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

4 participants