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

Attach scroll/wheel to root: alternative scroll browser locking fix #13460

Closed
wants to merge 11 commits into from

Conversation

nhunzaker
Copy link
Contributor

@nhunzaker nhunzaker commented Aug 22, 2018

This is an alternative solution to #9333 that attaches scroll/wheel listeners to the root container element.

So far, this prevents browser scroll locking in Chrome, Edge and Firefox. It does not appear to fix locking on Safari. However I think I might be getting inaccurate readings in BrowserStack and would really appreciate some help testing.

Test Plan

  1. Visit http://nh-react-scroll-root.surge.sh/scroll
  2. Scroll around using the window for 10 seconds
  3. Scroll around using the inner scrolling div for 10 seconds

Expected: No scroll locking

Browsers

  • Chrome 69
  • Edge 17
  • Firefox 61
  • Safari 11.1

Scroll events need to be attached locally in order to receive
rendering optimizations in Firefox, Edge, and Safari.

Unfortunately, scroll events can be nested. When attached locally,
events bubble up through both the DOM and React event systems.

This commit adds a module that tracks what events have
dispatched. When possible, it uses a WeakSet to test membership. When
the event is fully dispatched, it should be released with GC.

For browsers that do not support WeakSets, this module modifies the
event with a flag. This needs to be tested in IE.
trapCapturedEvent(dependency, root);
rootListeners[dependency] = true;
}
return;
case TOP_FOCUS:
case TOP_BLUR:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gaearon you mentioned that touch events were essential (#9333 (comment)), would you like me to add them to the list here?

@gaearon
Copy link
Collaborator

gaearon commented Aug 22, 2018

I was thinking that if we do this, we should do it for all events. And behind a feature flag (it will be a pain to deploy at FB and would need to be breaking change).

const dependencies = registrationNameDependencies[registrationName];
for (let i = 0; i < dependencies.length; i++) {
const dependency = dependencies[i];
if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
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'm going to revert this change. It isn't related to this work and should be done in a separate PR.

@pull-bot
Copy link

pull-bot commented Aug 22, 2018

ReactDOM: size: 🔺+0.1%, gzip: 🔺+0.2%

Details of bundled changes.

Comparing: e106b8c...1361a81

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js 0.0% 0.0% 649 KB 649.32 KB 152.36 KB 152.43 KB UMD_DEV
react-dom.production.min.js 🔺+0.1% 🔺+0.2% 95.3 KB 95.36 KB 31.17 KB 31.21 KB UMD_PROD
react-dom.development.js +0.1% +0.1% 645.14 KB 645.46 KB 151.24 KB 151.32 KB NODE_DEV
react-dom.production.min.js 🔺+0.1% 🔺+0.1% 95.29 KB 95.35 KB 30.89 KB 30.93 KB NODE_PROD
ReactDOM-dev.js +0.1% +0.1% 652.45 KB 652.87 KB 149.39 KB 149.48 KB FB_WWW_DEV
ReactDOM-prod.js 🔺+0.2% 🔺+0.2% 287.9 KB 288.36 KB 53.34 KB 53.46 KB FB_WWW_PROD
react-dom.profiling.min.js +0.1% +0.1% 96.49 KB 96.55 KB 31.29 KB 31.32 KB NODE_PROFILING
ReactDOM-profiling.js +0.2% +0.2% 290.25 KB 290.7 KB 53.94 KB 54.06 KB FB_WWW_PROFILING

Generated by 🚫 dangerJS

@nhunzaker
Copy link
Contributor Author

nhunzaker commented Aug 22, 2018

Cool. Doing that exposes a few failures. Particularly around mouse enter and leave because it needs to pick up movements outside of React. That might be fixable by attaching to the owner document only for those events.

@gaearon
Copy link
Collaborator

gaearon commented Aug 22, 2018

Note past attempt in #8117 and the uncovered difficulties.

@nhunzaker
Copy link
Contributor Author

Yeah. This is going to take some planning. Maybe we can talk about it at the DOM team meeting.

@philipp-spiess
Copy link
Contributor

philipp-spiess commented Aug 24, 2018

@nhunzaker I've tested Safari and Chrome and it seems that both browsers are still blocking at some point. Firefox seems good but I have not tried Edge. 🙂

Edit: Firefox also seems good when using 16.4.2.

@nhunzaker
Copy link
Contributor Author

Closing this out in favor of #9333. It looks like attaching to the root prevents the outer scroll region (the window in the fixture case) from being optimized in Edge and Safari. In #9333, I think I've figured out how to safely attach local listeners.

@nhunzaker nhunzaker closed this Aug 28, 2018
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.

5 participants