Closed Bug 1585378 Opened 5 years ago Closed 3 years ago

CSS position: sticky causes flicker while scrolling

Categories

(Core :: Panning and Zooming, defect, P3)

69 Branch
defect

Tracking

()

RESOLVED FIXED

People

(Reporter: andre, Assigned: hiro)

References

Details

Attachments

(5 files)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:69.0) Gecko/20100101 Firefox/69.0

Steps to reproduce:

  1. Navigate to https://ob02v.csb.app/
  2. Attempt to scroll (any direction, any method: trackpad, wheel, shift+wheel, drag on scrollbar)

Actual results:

You'll see substantial flickering of the content: https://cl.ly/5bfb0a3df1ba

Expected results:

No flickering should occur.

Interestingly, if you open the developer tools for the page, the painting works perfectly.

(Note: this example sandbox renders all of the elements, but this same issue occurs even with virtualization of the cells)

Component: Untriaged → Layout: Scrolling and Overflow
Product: Firefox → Core

Thanks for the report :)

I don't seem to be able to repro this on Nightly, does it repro if you use https://nightly.mozilla.org?

The devtools thingie may be because we disable paint skipping when devtools are open iirc?

Component: Layout: Scrolling and Overflow → Web Painting
Flags: needinfo?(andre)

Unfortunately, it does seem to happen on Nightly as well.

Here's a recording from a fresh download of nightly on a brand new profile with no configuration changes.

https://cl.ly/f3cf1ef64822

Flags: needinfo?(andre)

The priority flag is not set for this bug.
:mattwoodrow, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(matt.woodrow)

Is there any other information I can provide to help prioritize this bug?

Alternatively, is there a CSS property or other hint I can set as a web developer to disable "paint skipping" (per Emilio above) on a site?

It looks a bit like we're not pre-rendering enough content for side to side scrolling, so we get ahead of what's available very easily.

Any ideas botond?

Flags: needinfo?(matt.woodrow) → needinfo?(botond)
Priority: -- → P3

The screen recording links are not working for me. Andre, could you upload them to Bugzilla or link to the files directly?

Flags: needinfo?(botond) → needinfo?(andre)

I was able to view the recording links in Chrome; I filed a bug about not being able to view them in Firefox.

So the fact that the sticky table headers don't render when the page checkerboards, is a case of bug 1424714.

The fact that the page checkerboards in the first place... that might just be regular checkerboarding due to scrolling faster than we can paint, rather than an issue specific to this page / this page structure.

Does enabling WebRender (about:config --> gfx.webrender.all=true) help? WebRender helps a lot with checkerboarding on many sites, and I see a lot less checkerboarding on this site with it enabled.

Flags: needinfo?(andre)

Enabling webrender doesn't solve the problem on my machine unfortunately.

The regular checkerboarding of the main grid area is an understandable limitation, and I wouldn't necessarily expect that to be fixed. However, I do think that the sticky top and sides should remain visible 100% of the time since they remain static on the page. If you compare the above sandbox with Chrome, you'll see that even though the main grid area sometimes checkerboards, the sticky bits never do.

The issue you linked (and the issues stemming from there) do indeed seem similar, and have been open for years. Is this something that's unlikely to be fixed anytime soon then? Any timing related information you could share would be appreciated so that we might communicate to our customers and/or attempt workarounds.

Thanks!

(In reply to andre from comment #9)

Enabling webrender doesn't solve the problem on my machine unfortunately.

Ok, thanks for testing.

The issue you linked (and the issues stemming from there) do indeed seem similar, and have been open for years. Is this something that's unlikely to be fixed anytime soon then? Any timing related information you could share would be appreciated so that we might communicate to our customers and/or attempt workarounds.

Bug 1424714 is fairly high on my priority list, and I hope to do a pass over it and other position:sticky correctness bugs fairly soon after work on desktop zooming (my current project) quiets down a bit. (And subsequently to that, a pass over issues of scrolled content checkerboarding as well, because I think we can do better for simple pages like this testcase.) Let's say Q1 2020.

I did think about bug 1424714 a bit just now, to see if there's a quick fix we could deploy. I suspect the root cause is related to the issue described in bug 1548397 comment 6 (another position:sticky correctness bug), which will at least need some discussion with coworkers who are on vacation until January, so I wouldn't expect any movement before then.

In terms of a workaround, making the elements position:fixed instead of position:sticky should solve the problem. That should be doable for the attached testcase (since the top and sides are in fact fixed in place throughout), but of course I don't know if that generalizes to your actual application.

I will mark this bug as depending on bug 1424714, so we re remember to test this page after that bug is fixed.

Depends on: 1424714

Gotcha, glad to hear this is on your priority list!

position: fixed prevents the headers from staying in sync with the grid body (unless I'm missing something) - the only way I know of to do both a fixed header and side on a grid is with position sticky or with JS based synchronization, which has its own set of problems.

Thanks for the response, and please let me know if there's anything else I can provide to help you when you get a chance to look at this more deeply.

Bug 1424714 has been fixed recently, however I can still reproduce the issue of the sticky table headers disappearing during fast scrolling, so additional investigation is needed here.

Would be nice to hear an update on this. Issue is still reproducible in Firefox 81.0.1, however it is much better in Nightly 83.0a1.

(In reply to anantha from comment #13)

Would be nice to hear an update on this. Issue is still reproducible in Firefox 81.0.1, however it is much better in Nightly 83.0a1.

Nice to hear that it's improved!

If you're willing to take a bit of time to use mozregression to track down what improved it between 81 and 83, that would be useful to know.

(In reply to Botond Ballo [:botond] from comment #14)

(In reply to anantha from comment #13)

Would be nice to hear an update on this. Issue is still reproducible in Firefox 81.0.1, however it is much better in Nightly 83.0a1.

Nice to hear that it's improved!

If you're willing to take a bit of time to use mozregression to track down what improved it between 81 and 83, that would be useful to know.

So, I checked this with mozregression and I've had some weird results with it. When I searched between version 81 and version 83, none of the Nightly releases that opened from mozregression reproduced the issue. Anyway, the result of the search pointed to this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1518999
And this particular commit of the bug:
https://phabricator.services.mozilla.com/D86260

Inspecting the commit, shows its just test cases so I wasn't sure about the result.

So I ended up searching from a lower version(started from version 71). This time it did reproduce the issue in the Nightly releases the mozgression tool opened. And the search result pointed to this:
https://bugzilla.mozilla.org/show_bug.cgi?id=1646842

Now this interesting because you did point out that WebRender helps. So I tried enabling WebRender in Firefox 81.0.1, but that didn't help.

One more thing to note is that, all of this was happening in Mac OS X. So I tried reproducing this issue in Windows(same firefox 81.0.1) but it feels much better(lower flickering). Not sure if the difference between machines is a contributing factor.

It sounds like the issue reproduces in your existing Firefox 81 installation, but not in the version of Firefox 81 that mozregression downloaded. It would be interesting to track down what difference between the two might cause this.

One thing you could try is, in your existing installation, do "Help --> Restart with add-ons disabled", and see if the issue still reproduces. If not, it could be caused by an addon you have installed.

If that's not the case, another thing to check would be to go to about:support in each of the two versions, and compare the "Important modified preferences" sections to see if any prefs are different.

I am able to clearly reproduce this bug on Firefox 88.0 with the following web page:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Firefox "position: sticky" bug demo page</title>
    <style>
        body {
            margin: 0;
        }

        .sticky {
            position: sticky;
            top: 0;
            height: 50vh;
            background-color: darkslategray;
            color: lightgray;
            font-family: sans-serif;
            padding: 1rem;
        }
    </style>
</head>
<body>

<div class="sticky">This sticky DIV will flicker when the page is being scrolled quickly
    (e.g. by dragging the scrollbar handle with a mouse). I can clearly reproduce this bug
    in Firefox 88.0 on Windows. Other browsers don't have any issues with this page.
</div>

<script>
    // generate some DIVs to make the page complex enough (can be done without JS with the same result)
    for (let i = 1; i <= 120000; i++) {
        document.write(`<div>${i}</div>`);
    }
</script>

</body>
</html>

Just wanted to chime in that I can still reproduce this bug with the latest nightly (90.0a1 (2021-05-29), fresh/empty profile, no addons or changed settings) both with the testcase from the comment above and in a real-world scenario in a different page. If I change the element to position: fixed instead of sticky, the flickering disappears. Blink/Webkit browsers do not have this issue and the only workaround seems to be resorting to JavaScript hackery.

Is there any chance someone could give this another try of reproducing?

Flags: needinfo?(emilio)
Flags: needinfo?(emilio)
Attachment #9224168 - Attachment mime type: text/plain → text/html

I can repro with that test-case, and it seems related to checkerboarding in Graphics / APZ. Not sure if this is easy to avoid though.

Status: UNCONFIRMED → NEW
Component: Web Painting → Panning and Zooming
Ever confirmed: true

We have a cluster of issues around position:sticky content flickering / checkerboarding (this bug, bug 1415129, bug 1539443, bug 1635155). I'll try and see if I can get investigation of these prioritized.

I will start with this one since there is a test case I can easily reproduce the issue.

Assignee: nobody → hikezoe.birchill
Status: NEW → ASSIGNED

Hiro Assigned. Part of Jira Epic FFXP-370

So an (possible) issue I've found is here in nsBlockFrame::BuildDisplayList. The position sticky frame is inside the LineIterator and during the flicker is happening we skip building the display item for the sticky frame there because the ShouldDescendIntoLine(lineArea) returns false at that moment.

What I don't quite understand is the display list builder's dirty rect reached to the final scroll destination position pretty soon, whereas the LineIterator's ink overflow rect is increasing gradually, presumably it's increasing in response to each StickyScrollContainer::ScrollPositionDidChange call. I am supposing this difference is the root cause of the flicker.

I've reached the source of the flicker. That's apz.peek_messages.enabled. Disabling apz.peek_messages.enabled solves the flicker. I have zero knowledge about the pref, I will learn how it's supposed to work, will figure out a way to solve this flicker.

All bug 1635155, bug 1539443 and bug 1415129 are solved by disabling apz.peek_messages.enabled. Though in the test case in bug 1635155 comment 5, disabling apz.peek_messages.enabled solves the sticky header's flickering, but checkerboarding still happens in the scroller, it's much faster than Chrome though.

See Also: → 1415129, 1539443, 1635155

The peek messages machinery was introduced in bug 1242609. BenWa left some pretty useful information there. From bug 1242609 comment 2;

We used to have IPC compression on UpdateFrame however it was removed for sub-APZ because IPC compression was not flexible enough and was doing the wrong thing leading to bugs:

I actually tried to specify "Compress" or "Compress=all" to RequestContentRepaint, but it didn't solve the flicker at all. And thanks to the BenWa's comment, I will never try to manage to make it work as expected. :)

So the only one way I can think of to solve this flicker is update sticky container's position in UpdateDisplayPortMarginsForPendingMetrics. It sounds tricky to me though.

See Also: → 1242609

Just simply invoking StickyScrollContainer::ScrollPositionDidChange didn't help at all. In fact, it looks worse then before.

And interestingly with this patch, the LineIterator for the position:sticky in question isn't iterated..

Depends on: 1730993
Depends on: 1730998

Setting apz.peek_messages.enabled to false does eliminate the flicker for me, but introduces some shifting.

Confirmed I can no longer see any flickers on the test case in comment 19 on the latest nightly (the build id: 20211014212856)

Closing.

Gregory if you still see the shifting on the latest nightly, please open a new bug. It's probably a different issue. Thanks!

Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Flags: needinfo?(email.greg.email)
Resolution: --- → FIXED

(In reply to Hiroyuki Ikezoe (:hiro) from comment #31)

Confirmed I can no longer see any flickers on the test case in comment 19 on the latest nightly (the build id: 20211014212856)

Closing.

Gregory if you still see the shifting on the latest nightly, please open a new bug. It's probably a different issue. Thanks!

Unfortunately I can still the shifting on the latest Nightly, the flickering is gone though!!! I will file a new bug for this problem, thanks!

Flags: needinfo?(email.greg.email)

I see this ticket has been closed and marked as "RESOLVED FIXED", but looking at the original test case, seems like the issue persists. Specially when compared to how Chrome handles it. See video attached above for comparison.

Are there any plans to improve this further?

Thanks.

I can see a little bit of flicker sometimes if I try really hard. Hiro, do you want a new bug or reopen this bug?

Flags: needinfo?(hikezoe.birchill)

Yes, please. To be honest, I probably didn't test horizontal scroll case here. And I won't spend time on the bug for now since I believe, even though horizontal sticky element is sometimes flickering, overall looks much better than chrome.

Flags: needinfo?(hikezoe.birchill)

Fabio, would you mind filing a new bug for the issue? Thanks!

Flags: needinfo?(me)

Sure thing. Will do.

Flags: needinfo?(me)

Hiro, new bug here.

Thanks for the work so far.

Flags: needinfo?(hikezoe.birchill)

Thank you Fabio!

Flags: needinfo?(hikezoe.birchill)
See Also: → 1795784
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: