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 tracks scroll position internally and forces synchronous layout #1300

Closed
steadicat opened this issue Mar 24, 2014 · 12 comments · Fixed by #6129
Closed

React tracks scroll position internally and forces synchronous layout #1300

steadicat opened this issue Mar 24, 2014 · 12 comments · Fixed by #6129

Comments

@steadicat
Copy link

React adds a scroll listener that tracks and caches the scroll position (I assume for some undocumented internal purpose). Additionally, the scroll listener forces a synchronous layout (see screenshot). This seems wasteful, especially considering that the values tracked are never exposed in the API.

What is the scroll listener used for? Can it be removed?

screen shot 2014-03-24 at 3 11 09 pm

@sophiebits
Copy link
Collaborator

ViewportMetrics is used to normalize pageX and pageY on mouse events: SyntheticMouseEvent.js#L63-L73. Perhaps ironically, it was created to prevent synchronous layouts during mouse event handlers.

@gaearon
Copy link
Collaborator

gaearon commented Apr 23, 2014

I wish these values (as well as the event) were somehow exposed.

@mietek
Copy link

mietek commented Aug 18, 2014

👍

@gaearon
Copy link
Collaborator

gaearon commented Aug 18, 2014

BTW you can obviously have this if you use a Webpack-like bundler:

// get_scroll_y.js

'use strict';

var ReactBrowserEventEmitter = require('react/lib/ReactBrowserEventEmitter'),
    ViewportMetrics = require('react/lib/ViewportMetrics');

ReactBrowserEventEmitter.ensureScrollValueMonitoring();
ViewportMetrics.refreshScrollValues();

function getScrollY() {
  return ViewportMetrics.currentScrollTop;
}

module.exports = getScrollY;

@syranide
Copy link
Contributor

Well, ViewportMetrics is only used for IE8 and possibly other very old browsers (http://www.quirksmode.org/mobile/tableViewport_desktop.html), so we should be able to just disable it for all other browsers and everyone is happy right? (Could still be optimized slightly for IE8... if anyone cares)

Also,
https://github.com/facebook/react/blob/master/src/browser/ui/ReactEventListener.js#L65
https://github.com/facebook/react/blob/master/src/browser/ui/ReactEventListener.js#L165

That makes no sense at all to me, refresh does not take an argument, yet we get the scroll position and provide it as an argument. Instead, refresh gets the scroll position internally and uses that? So we call getUnboundedScrollPosition twice, but only use the result once (also, this should be broken for events inside iframes, for IE8).

Also2,
https://github.com/facebook/react/blob/master/src/browser/eventPlugins/TapEventPlugin.js#L54
I'm pretty sure any browsers that supports touch, also supports pageX.

cc @spicyj

@sophiebits
Copy link
Collaborator

I agree that we shouldn't be tracking it in other browsers if we don't need it. I don't know if there's a way to predict whether we'll have .pageX and .pageY before mouse events actually come in.

@syranide
Copy link
Contributor

@spicyj document.createEvent && 'pageX' in document.createEvent('MouseEvent') :)

@syranide
Copy link
Contributor

Another idea being just let resize/scroll set a flag, when a mouse event is created, if the flag is set, update viewport metrics. That way we only update it when needed, but could potentially cause a reflow if there are other events before it (very unlikely though I imagine).

@michalzubkowicz
Copy link

This issue causes React based longer lists unusable on mobile.

@lo1tuma
Copy link

lo1tuma commented Sep 8, 2015

Is there any progress on this issue? I’m not sure if this is the root-cause for pages rendered with react scrolling extremely slow with firefox mobile on android (e.g. this react website http://isomorphic500.herokuapp.com/featured/highest_rated).

@sophiebits
Copy link
Collaborator

@lo1tuma Is that your site? If so, you can try commenting out the logic in refreshScrollValues to see if it makes a difference. If it does, I'm happy to prioritize @syranide's #2271 and try to get it in.

@lo1tuma
Copy link

lo1tuma commented Sep 9, 2015

@spicyj No, that is not my site, it is an example react & fluxible page (see: https://github.com/gpbl/isomorphic500), but we have exactly the same issues with scrolling on firefox mobile.
I’ve applied the changes in #2271 manually and it doesn’t solves the problem, so this issue might be unrelated to my problem. I will investigate further.
Thanks for considering to prioritize this. Much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants