Slow scrolling in Chrome due to replaceState bug

(lid) #1

I haven’t really isolated the problem but I will start by how to replicate it.

This issue best can be replicated with a topic that has more then 2 posts that are not visible on the bottom

Tested on: Chrome, Windows 8,i7-4500u

At first I thought the issue was related to the header change ( the move of the logo and the title on the top area when you scroll down a little bit from the top )

But then I realized that I am getting “jump” when the url is changing.

every time I scroll enough to trigger that url change I experienced the slowness.
the interesting part is that I don’t have to scroll thorough the topic, sometimes only scrolling to the 2nd post will cause it(depend on the length of the posts and screen resolution).

It is possible that the “url change” is not the main cause for this issue but perhaps a symptom.

I experience a similar behavior with general scrolling in android, I suspect the mobile and desktop may be affected by the issue.

I wonder if it is possible to disable the url change for testing purposes and see if it improve the scrolling.

this issue might not be noticeable on fast machines

(Sam Saffron) #2

You can easily do it from console, read through the source of: Suppress updating of URL during topic navigation it is trivial.

(lid) #3

Thanks @sam

did the trick
Discourse.TopicRoute.disableReplaceState = true;

I can now confirm that this fix the slow scroll issue on desktop, I did not test it on mobile yet.
it is needless to say that having the post id populated in the URL is actually a useful feature , url sharing ,etc(isn’t it?)

Do you think it will be possible instead of disabling it completely, to effectively trigger the update after the user finished scrolling.

on android mobile device, the URL bar is hidden on scroll down. so there is not much benefit updating the url while scrolling down on that device.

(Sam Saffron) #4

We already debounce it, but I guess we could debounce it more. On mobile due to inertia you would be talking about a multi second debounce.

Personally, I want to only replace state when you navigate away, but @codinghorror and @eviltrout really like the current behavior.

(lid) #5

I just disabled the URL update on my android device, it is hard to tell performance gain.
In the mobile device the scrolling experience is probably affected by other factors as well

but oh boy on my desktop it made scrolling fun , big improvement for experience.

Another factor to take into consideration when we triple debounce is the screen resolution.
from my experiment on my device the URL does not even show the end of the url not in landscape or portrait mode.

I am not sure what mobile device will actually show the end of the url except when the user actually click on the url bar.

My recommendation for desktop is that the url will only update after scroll finished which can be difficult to predict.
but at least not to update in the middle of scrolling. I guess the bounce help but not solve the issue completely

(Jeff Atwood) #6

I see no “jump” when scrolling on my Win8 / Chrome desktop, can you perhaps make a video? No other reports of this either.

I do have problems scrolling on Chrome Android beta, but not in Chrome Android release.

(lid) #7

What are your comp specs?

I don’t think making a screencast will be fair, is it will overload the cpu even more.
which can actually increase the affect or might even create a total frame drop.

I don’t have a screen capture software at hand, I can look for one if it is that important.

or we can create a test page one with the feature enabled, one with the feature disabled and ask for feedback from users about the scrolling experience.

(lid) #8

but if you insist:

You can download flv from here. ~18mb

for the test i hide all images using jquery $(“img”).hide() to reduce noise of image renders.

I only captured the header of the browser with chrome FPS visible other wise the recording was slowing the system so much that the graph gave no meaningful results.

test 1 (url change on)
Time 0:00-0:15

test 2 (url change off)
Time 0:15-0:30

test 1.1 (url change on)
Time 0:31-0:45

test 2.2 (url change off)
Time 0:46-1:00

with uri ON ( slow)

with uri off ( fast)

(caue rego) #9

I’m on a mbp 2013 i7 with 8gb with an SSD and I can experience this issue, though it’s so minor I would never have noticed it have you not said it existed. Maybe I’m also experiencing it because I got so many chrome tabs open at same time…

In any case, I don’t think it would be that hard to implement the javascript in a way to only change the URL after scrolling stopped completely. Why not aim for the better behaviour? I could toy with this myself if you think it’s doable, @codinghorror or @Sam. Since it’s nothing critical, I could do it in my own time. :stuck_out_tongue:

(Jeff Atwood) #10

I agree, it’s an extremely minor thing – I have never noticed it across dozens of different computers and devices I have used to access Discourse… granted very few of them were “low end”, but we are building for the next 10 years (well, 9 years now) of the Internet, not the previous 10.

(lid) #11

Interestingly enough the machine I use is by no mean low end. And I will not consider a Mac book pro 2013 a low end.

It is almost evident that computers are getting smaller,lighter,and surprisingly speed is not a top priority any more. Battery life on the other end is. And I guess my CPU doesn’t think it should turn on another core for scrolling through a bunch of text. And well it shouldn’t

Personally I have the choice
I can put my computer at performance mode have a smooth scroll but my battery will run out of juice in 3hr or I can work on a mode that will give more then 7 hr. And do work on the background.

I am not saying support “low end devices” by stopping innovation.
But if you have a working horse. You are not going to ask it to dance while he work, just because he can. It might be cool to have a such a horse. He might even be the house of the next century. But riding that horse sure going to bumpy.

Computers get smarter every day. Programmers should keep up.

(Jeff Atwood) #12

I simply have no idea what you are talking about.

Now you mean CPU usage? You didn’t mention this before. Why didn’t you show a CPU graph if that was the case.

  • On Chrome / Windows, I don’t see any smooth scrolling, it simply scrolls one indent or one spacebar every time. No noticeable performance issues, no hitching.

  • On iPad the scrolling is quite smooth. (I don’t have any Macs) I can’t recall seeing any hitching or pausing in scrolling.

  • On Chrome, Android (current) scrolling seems as expected, I notice no hitches. However on Chrome Android beta there appears to be a new bug where scrolling stops working altogether.

I guess if I could see or understand what you’re talking about on any computer I have access to? What are the steps to reproduce? Perhaps this is an issue of sensitivity?

also see:


Which I think already cover the “feeling” ground…

(lid) #13

Are you talking about the horse story or in general?

It is actually quite simple

  1. Disabling the URL change on scroll makes scrolling smoother. I can personally see it and experince it after all I open this topic as bug. I was even able to record fps graph to shows the drops, drops that are translated on my computer to scrolling lag.

The fact that I was able to eliminate the lag by disabling the feature using js, is more then enough for me to understand the correlation.

the CPU example was to explain that I can “overclock” my machine to be faster, use more battery so I can have smooth scroll, but I don’t really have to because I can have smooth scrolling by tweaking the js, which is enough proof, that this feature could be improved on the code level(without losing the functionality). And that a fix is not necessarily hardware dependent.

I was able to replicate the issue in 4 different ways of input ( all on the same machine )

  1. scrolling using the laptop trackpad (1st used when I noticed the issue)
  2. using a mouse but dragging the scrollbar handle
  3. dragging the screen up and down using the touchscreen
  4. using the keyboard down/up arrow

(I have used the keyboard key down to run the tests and the fps recording.)

but if you are using the mouse scroll by rotating or swiping it (middle button) then this scroll is more likely incremental scroll which is obviously more difficult to see lag using it even on “low end machines”

Another symptom is when I experience the lag in the scroll the favico on that chrome/tab may flicker.

I opened this topic to raise awareness of a problem I personally experience.
I contributed my finding hoping that it can benefit the community and the project.
@sam helped me to isolate the culprit and testing performed returned with positive results.
fixing this issue may not affect everyone, but it is evident enough that there is a problem.

I am actually curious to know if more people experience that issue , but so far you and @cawas are the only people so to contribute their personal experience with the issue. I think that further investigation should be taken place.
I wish there was an easy way to prove that the issue is just there unfortunately it is a tricky one.

I originally suggested setting up a test topic and ask for users feedback to the scrolling experience.
sort of like A/B testing.

but may be this issue is really that minor that is not worth the effort.

(caue rego) #14

Again, just tell me it is doable and I’ll fork it. The URL doesn’t need to keep changing while scrolling, only when it stops. Why not just do it that way?

(Sam Saffron) #15

It is pretty provable that replaceState has performance impact in Chrome, take this example: (source: JS Bin - Collaborative JavaScript Debugging)

On this simplistic page at a 20ms interval I can see a single core on my computer go to 100% and scroll perf degrades a lot. This happens cause Chrome does a pile of work on replaceState (generating thumbnail, accessing local bookmark db and so on), the bigger and more complex the page the more work there is to do.

I think there is no harm really in debouncing the replaceState stuff a bit further, maybe to 2 seconds after scroll finishes (skipping if mouse is down so people with finger on the scroll bar dont get hit with it) with a guard that always replaces state if you navigate away. That said, I do not think we have time to muck with this now, its going to have to come from the community or wait till post v1.

(Jeff Atwood) #16

So this is a Chrome specific issue? Chrome Windows, or Chrome Mac? Looks like it has been a bug for a while

(Sam Saffron) #17

Totally Chrome specific, no repro in IE or Firefox. I can make it happen both on Mac and PC.

I don’t think this is properly reported, I will report it now and ping Paul Irish about it.

Edit: raised 392333 - replaceState can cause high CPU usage and janky scrolling - chromium - Monorail

(lid) #18

@sam on firefox I got the lag as well, but could be that chrome suffer a bigger performance impact.( but I also didn’t test firefox as much)

We can consider using _.debounce() the way it behaves on chrome( also firefox) with the scroll event is interesting. the even callback is called only when the user stopped scrolling.

you can scroll the entire 5000px in the example below, and the event will fire once when you stopped the scroll if you were quick enough
##debounce scroll - JSFiddle

(Sam Saffron) #19

Canary is also a bit better in this department, we are open to a PR in this area if you can thoroughly test it. It is just that we can not afford to spend too much time on this now.

(lid) #20

We should probably move this topic back to bug category.