bvaughn / react-virtualized

React components for efficiently rendering large lists and tabular data
http://bvaughn.github.io/react-virtualized/
MIT License
26.3k stars 3.05k forks source link

Scroll performance issues in Firefox #518

Open zsherman opened 7 years ago

zsherman commented 7 years ago

I'm using the classic combo of CellMeasurer and Grid to do some fancy infinite scrolling. Everything looks/works great in chrome but I've noticed some serious performance issues in Firefox. At first I thought it was just my implementation or that I was re-rendering too often but then I noticed this warning:

This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features!

Turns out the demo here http://bvaughn.github.io/react-virtualized/#/components/CellMeasurer actually suffers from the same performance issues and has the same warning:

screenshot 2016-12-29 11 25 47

The uniform width and height demo is particularly glitchy fwiw.

Anyone dealt with this before?

*FF Version: 50.1.0

zsherman commented 7 years ago

On a somewhat related note I'm also noticing odd scrolling behavior with the demos on the latest version of Safari. It seems there is absolutely no momentum when scrolling whatsoever, here's a quick gif I snapped which hopefully shows what I'm referring to. Keep in mind that I'm doing full force scrolls here but the list only adjusts by a few rows at a time:

http://recordit.co/nnxk3cd7Q3

Happy to open a separate issue if you think this is unrelated @bvaughn, could it be related to the introduction of the style cache in 8.8?

bvaughn commented 7 years ago

Hey @zsherman,

Thanks for the detailed report! I haven't been ignoring it (despite my lack of a response) I've just been busy. It seems legit and I'll try to look into it when I can find/make time. Just wanted to leave a note to say that I appreciate the level of detail, and I am at least aware of the issue. 😄

bvaughn commented 7 years ago

From the Mozilla docs:

The definition of a scroll-linked effect is an effect implemented on a webpage where something changes based on the scroll position

This seems like a core part of the definition of what a windowing library does.

Moz says to replace as many scroll-linked effects as possible with CSS equivalents, but they also admit that not everything has a CSS equivalent

In many cases, scroll-linked effects can be reimplemented using CSS and made to run on the compositor thread. However, in some cases the current APIs offered by the browser do not allow this. In all cases, however, Firefox will display a warning to the developer console (starting in version 46) if it detects the presence of a scroll-linked effect on a page.

My initial reaction was to just write this off as one of those examples- but I don't see this same warning when looking at eg the fixed-data-table demo page. Need to look further at why this is.

zsherman commented 7 years ago

Hm that's definitely odd, what version of firefox are you running? Are you also able to reproduce similar scrolling issues on safari latest?

bvaughn commented 7 years ago

Firefox 50.1.0 (latest). Safari latest (10.0.2) performs great for me, similar to Chrome. Firefox performance is definitely the worst of the 3 by a noticeable amount.

zsherman commented 7 years ago

Good to hear that the newest version of Safari works well for you – I'm actually still on 9.1 and it will barely let me scroll, kinda crazy.

bvaughn commented 7 years ago

Ah. Safari 9 had a long-standing problem (#370) that was fixed forever ago in the Safari Tech Preview but only recently fixed (a couple of months ago) with the release of Safari 10. Best I could tell, Safari would interrupt its own scrolling animation if it detected any perpendicular movement. I was unable to find an acceptable workaround for that that didn't also damage performance.

zsherman commented 7 years ago

Gotcha, thanks for the heads up.

zsherman commented 7 years ago

@bvaughn just wanted to hop back in here and confirm that the issues with Safari are happening on 10.0.2 as well, would you like me to open a separate issue?

bvaughn commented 7 years ago

Momentum scrolling works fine for me in Safari, just re-tested with 10.0.3. Has worked fine for me with every 10.x version I've tried.

You can open an issue if you'd like. I'd probably mark it as "needs help" though.

danburzo commented 7 years ago

@bvaughn there's a thing in Firefox called Multiprocess Windows that you can inspect if you go to about:support. We've seen incredible differences from 0/1 disabled to 1/1 enabled, and as far as I can tell, the flag is enabled/disabled depending on the user (might be some sort of A/B test).

bvaughn commented 7 years ago

Interesting. Thanks for sharing!

Mathieuu commented 7 years ago

I observed the same thing on the web-app I am working on. This is what happen when I try to scroll smoothly

scrollp

Basically, it scrolls down a bit, then freeze the scroll completely (probably to do some computation) and start again.

It works great in Chrome, Safari and Edge and Firefox without multi-process (the scroll doesn't interrupt)

With multi-process, I think the UI is running in a different process. My guess is that the scroll thread synchronize once in a while with the javascript thread and freeze the UI until it gets an answer. Not sure how to fix that if I am right.

danburzo commented 7 years ago

@Mathieuu that's curious! On our project it runs as smooth on Firefox multi-process as on Chrome and Safari. It is with it disabled that the scroll starts to become janky.

bvaughn commented 7 years ago

Wish I knew some Firefox engineers to reach out to for guidance on this one.

@Mathieuu that GIF you attached looks rough (performance wise). Don't suppose that's anywhere I could take a look at?

Mathieuu commented 7 years ago

The elements we are rendering are pretty heavy. Performances have always been a challenge for us so it may be an extreme case.

Our product is a Firefox addon and we use a legacy addon API which automatically disable multi-process in Firefox. So you won't be able to reproduce with it. The gif you saw is an attempt to port our addon to the new API and multi-process.

However, I can also reproduce in the playground we use to develop our components (react-storybook). If you are interested, I could prepare a version where the problem would be easily reproductible.

bvaughn commented 7 years ago

@Mathieuu Sure, if you are able to. It might be helpful for me to take a look.

Mathieuu commented 7 years ago

Actually, the issue is already reproductible in: http://localhost:3001/#/components/Grid by scrolling horizontally quickly enough.

Download Firefox Nightly. Go to about:support and check that Multiprocess windows is enabled.

Otherwise, it can be enabled in Firefox / Preferences / General / Startup or by setting to true browser.tabs.remote.autostart in about:config.

To reproduce the lag I have set dynamic row and set a column overscan of 100. The idea is to make each row heavy enough so we can see the freeze. If it doesn't work with 100, try with 1000.

I am running on a Macbook Pro 13" 2015 Retina, and scroll with the trackpad (which allow to scroll quicker than my mouse)

scroll2

Without multi-process, the whole interface feels a bit slow but there is no big freeze like that.

bvaughn commented 7 years ago

To reproduce the lag I have set dynamic row and set a column overscan of 100. The idea is to make each row heavy enough so we can see the freeze. If it doesn't work with 100, try with 1000.

Hm... with overscan rows at 10, cranking overscan columns to 100 means that each scroll event you'll be creating 1,800 React elements and thrashing the DOM a lot. I think it's understandable that the browser lags behind a bit in that case. Chrome does too.

Mathieuu commented 7 years ago

Those instructions were written to make the problem big enough so anyone could reproduce no matter the hardware or the scroll speed.

But as mentioned in the first post, the issue is also partially visible in the demo without changing the parameters.

Even with my heavy tests, Firefox without multi-process manages to provide an almost smooth experience and so does Chrome. But as soon as multi-process gets activated, the scrollbar freezes every X elements.

rickychien commented 7 years ago

I ran into this issue after adopting react-virtualized as well. The root cause could be due to APZ (Async Panning and Zooming).

A simple way to verify:

  1. Visit about:config in Firefox
  2. Search layers.async-pan-zoom.enable and set it to false
  3. Restart browser
  4. Run example https://bvaughn.github.io/react-virtualized/#/components/Grid

Bug has reported, please see https://bugzilla.mozilla.org/show_bug.cgi?id=1346159

bvaughn commented 7 years ago

Thanks for the update and the bug link @rickychien! I'm pretty bummed to see that it looks like RV might not make it in for the RequestList because of this issue. Is there anything I can do to help? Let me know if so!

qtuan commented 6 years ago

Here is another observation of performance issue on Firefox, hopefully useful for this issue.

On the demo: https://bvaughn.github.io/react-virtualized/#/components/WindowScroller. When "Use custom element for scrolling" is unchecked, scrolling is very smooth. When it is checked, scrolling is much worse, almost unusable. Tried turning APZ on/off but no difference.

So performance can be good/bad on the same Firefox. Maybe this is a sign that the issue do not only lie in the Firefox itself?

(Firefox 56.0.2 64-bit)

skirdey commented 6 years ago

Experiencing freezing issue on Firefox 57.0.4 - Firefox displays following in console: This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features!

mkarajohn commented 6 years ago

Glad I found this thread.

I am working on a page that is supposed to be showing a long grid of cards. I am using WindowScroller with a List.

I am working on 2 screens, my laptop's (Macbook Pro 13'' 2015) and an external 1920x1080 screen.

I have noticed that in general the WindowScroller performance while scrolling on Chrome on the external screen is quite bad. This also happens on my Windows machine, where I only have a 1920x1080 screen. Firefox, Safari and Edge on the other hand scroll very smoothly.

The same performance is noticable when working on another page that does pretty much the same thing, using WindowScroller with a Table instead of a List

Firefox: https://gyazo.com/313bed802824359874353911701a9149

Chrome: (it may look as if the page is not moving but in truth I was scrolling the whole time) https://gyazo.com/451d9de720c2878a623c83d370ca8276

Safari: https://gyazo.com/f08bd551411abe4ffa31d30d1af29bf0

All the gifs are taken from my external screen. On my laptop's screen scrolling performance is fine on all browsers.

bvaughn commented 6 years ago

I have noticed that in general the WindowScroller performance while scrolling on Chrome on the external screen is quite bad.

Is the external monitor screen (and hence the browser window) significantly larger by chance? This can have an impact on performance.

Otherwise, this might indicate that hardware acceleration isn't being used for your external monitor.

mkarajohn commented 6 years ago

Is the external monitor screen (and hence the browser window) significantly larger by chance? This can have an impact on performance.

Yes, it is physically larger, but pixel count should be greater on my laptop's screen, since it's a retina display and operates at its native resolution (1920x1080 on the external vs 2560 x 1600 native).

My Windows machine by the way is equipped with a GTX 1060 graphics card and a 1920x1080 screen, yet Chrome's performance there is the worst still.

Otherwise, this might indicate that hardware acceleration isn't being used for your external monitor.

I forgot to mention, I have tried this (on my laptop). I deactivated hw acceleration, expecting that now scrolling performance should be poor in my laptop's screen as well, but it didn't make any difference.

Actually let me retest this and I'll update this post.

UPDATE: Ok, I just retested with hardware acceleration off. It makes absolutely no difference on performance parity for Chrome on the external screen vs laptop screen.

Also just to make it clear, I do not consider this a bug of the library; it is obvious that this has something to do with the inner workings of Chrome. I just thought to share my findings because I found it odd, and this thread looked like the place.

UisgeBeatha436 commented 5 years ago

I noticed this behavior too in FF 64.0b6 (64-bit). The example I took from https://codepen.io/rdallaire/pen/apoyx is working fine in the codepen, however if I put the code in my local site, I get the warning in FF and the scroll to top doesn't work.

During development I make use of a build tool, maybe that can help in the discussion.

sara-02 commented 5 years ago

I also came across this issue while viewing TED on Firefox.

This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features!

System's config:

Firefox: 66.2 for Ubuntu canonical
Ubuntu: 18 LTS