Open Bug 1103394 Opened 10 years ago Updated 2 years ago

When scrolling Twitter across transition-threshold between small profile-photo & large one, the viewport flashes a mis-scrolled view for an instant

Categories

(Core :: Layout, defect)

x86_64
Linux
defect

Tracking

()

REOPENED
Tracking Status
firefox44 --- affected
firefox45 --- affected
firefox46 --- unaffected

People

(Reporter: dholbert, Unassigned)

References

()

Details

Attachments

(5 files)

STR:
 1. View https://twitter.com/PrivateMe in a fairly large browser-window
    (The size matters because Twitter has different styles depending on size)
    (~1200 by 800 px works for me)

 2. Try scrolling up and down (e.g. with arrow keys) right around the point where the large profile-photo turns into a small profile photo and joins into the header-bar. Pay close attention when you scroll *up* (when the large version slides back into view)

ACTUAL RESULTS: The page flashes a mis-scrolled state as a part of this scrolling up transition.

I can reproduce in Firefox nightly; cannot reproduce in Chrome.  Happens with e10s enabled or disabled; doesn't matter.

Mozilla/5.0 (X11; Linux x86_64; rv:36.0) Gecko/20100101 Firefox/36.0
Version 36.0a1 (2014-11-21)
Ubuntu 14.10 64-bit


I'm not sure if this is a layerizing/un-layerizing artifact, or if perhaps it's even "correct" given the content that Twitter serves (but Chrome skips over it for some reason).

Attached screencast shows the bug at around 3 seconds in, on my second "scroll up" attempt. (I can actually see this bug happening on nearly all of my scrolls across that threshold, but my screen-casting program isn't fast enough to capture all of the the buggy frames, so it didn't capture all the instances of the bug in this session.)
Forgot to mention:
 - You don't need to be logged into twitter (and you should dismiss the "log into twitter" popup on first pageload)

I can reproduce this in Firefox release version, too (v33), so not a regression (or not a recent one, at least).
I'm going to attach a sequence of four frames, from the video, to make the bug easier to see.
 frame1 is just as I initiate the scroll-up action
 frame2 is the buggy mis-scrolled "flash"
 frame3 and frame4 are correct scrolling intermediate-points (similar to frame1, not to frame2)
Summary: When scrolling Twitter & transitioning between small profile-photo & large one, the viewport flashes a mis-scrolled view for an instant → When scrolling Twitter across transition-threshold between small profile-photo & large one, the viewport flashes a mis-scrolled view for an instant
When the header transitions from fixed ("locked") to scrolled ("unlocked"), two things happen:
 (1) The class "is-locked" is removed from the element with class "ProfileCanopy". This causes the element with class "ProfileCanopy-inner" (which is a child of .ProfileCanopy) to change from position:fixed to position:relative.
 (2) The margin-top inline style on the element with class "ProfileCanopy-header" is changed from something negative (e.g. -253px) to 0px.

(1) happens from a scroll event handler, which calls requestAnimationFrame, and the animation frame handler does (2). So if we render a frame between (1) and (2), the whole page content is moved upwards due to the negative margin that hasn't been removed yet.

Interestingly, in the reverse transition, i.e. 0px to -253px, the margin value is set directly from the scroll handler and not from the requestAnimationFrame callback.
(I found these things out using the Chrome developer tools which let you break on DOM attribute modifications.)
Sometimes we can also get into an inconsistent state when scrolling *down*, in which the reverse is true: The header is fixed / locked, but margin-top is still 0px. In that state, the header image briefly overlaps a large part of the page. I'm not quite sure how we can get in the state, but one guess is that it happens if you quickly scroll up and then down so that two scroll events fire without an animation callback in between. Like this:

1. You start out scrolled down, in the locked state, and the header has margin-top: -253px.
2. You scroll up, which causes a transition into the unlocked state. The header becomes position:relative from inside the scroll handler, and an animation frame is requested with a callback that will set margin-top to 0px. But this callback doesn't fire yet.
3. You scroll down, which causes a transition back into the locked state. The header becomes position:fixed and margin-top is set to -253px, but it already has that value.
4. The animation frame callback fires and sets margin-top to 0px.
5. Somehow, soon after, another animation frame callback corrects the margin-top back to -253px.

I'm not sure whether steps 4 and 5 are really what's happening, but it's at least one explanation for what I'm seeing.

It's possible that this scenario can only happen with APZ, which can lead to multiple scrolls being enqueued in the event queue of the content process, which increases the chance of them being dispatched as scroll events without a refresh tick in between.
We could ask Twitter to fix their code, or we could change the way scroll events are dispatched. For example, we could always dispatch them at the start of a refresh driver tick, such that animation frame requests from inside the scroll handler will be handled in that same refresh tick.
By the way, both of these "flashes" also happen in Safari 9.
(In reply to Markus Stange [:mstange] from comment #9)
> We could ask Twitter to fix their code, or we could change the way scroll
> events are dispatched. For example, we could always dispatch them at the
> start of a refresh driver tick

We do this now.

> such that animation frame requests from
> inside the scroll handler will be handled in that same refresh tick.

Not sure if we do this now, though. It's worth re-testing this bug to see if it still happens.
(In reply to Kartikaya Gupta (email:kats@mozilla.com) from comment #11)
> Not sure if we do [...] now, though. It's worth re-testing this bug to see if
> it still happens.

From a few minutes of testing, this seems to be WORKSFORME in current nightly. Tried repeating the process shown in the attached screencast over and over, and I didn't see any flashes of mis-scrolled content.  I tried in my normal browsing profile with e10s disabled, as well as in a fresh profile with e10s enabled.

Resolving as WFM.
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → WORKSFORME
(Nightly version in comment 12 is 46.0a1 (2016-01-05).)
Same for me ! Thanks for the work !
Note that in v45 it still happens though. It's likely fixed in v46 only.
Actually I see this again now.
Status: RESOLVED → REOPENED
Resolution: WORKSFORME → ---
And from mozregression this is old :/

Here is a pushlog, I couldn't make it better because builds are deleted from taskcluster:
https://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=8ef94be995a453f5c464278c53478ba8c8554f81&tochange=eb25b90a05c194bfd4f498ff3ffee7440f85f1cd
(In reply to Julien Wajsberg [:julienw] from comment #17)
> Actually I see this again now.

I can't reproduce in current Nightly, FWIW -- though I *also* can't reproduce in a Nightly from the day when I filed this (2014-11-22) launched via "mozregression --launch 2014-11-22 https://twitter.com/PrivateMe", so take my results with a grain of salt.

Maybe this bug depends on the recent content in the twitter feed in question, or some other special factor. Are you able to repro at https://twitter.com/PrivateMe ? (and/or any other specifics that might be relevant?)
Actually I think they now removed this behavior: the picture is no longer fixed on the left side after scrolling, now it just scrolls up.
(In reply to Julien Wajsberg [:julienw] from comment #21)
> Actually I think they now removed this behavior: the picture is no longer
> fixed on the left side after scrolling, now it just scrolls up.

That just happens if your window is too skinny. If you make your window wider, you should still see the image becoming fixed as shown in the attached screencast. (That's what I still see, at least.)
Ah yes, thanks for correcting me.
So I don't repro now, but I also have a faster computer than before. I'll retry on another slower computer.
I am getting a similar bug in Tumblr and some other sites. The pages flashes and jumps if I try to scroll up and reach an image. And I can't really make my window any wider than my screen, so that's not a solution.
I filed my own bug report, but can't find it. Firefox 57 is affected, haven't tested 58. In addition to Linux, MacOS is affected. May depend on screen size-- I am using a small laptop, and reduced resolution so I can read the system text.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: