Open Bug 1418923 Opened 4 years ago Updated 6 months ago

When filter blur applied to background-attachment:fixed, the browser flickers on scroll

Categories

(Core :: Web Painting, defect, P2)

57 Branch
defect

Tracking

()

People

(Reporter: roland, Unassigned)

References

(Depends on 1 open bug)

Details

(Keywords: testcase)

User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Build ID: 20171112125346

Steps to reproduce:

When CSS filter blur applied to an element which has fixed background image, it start to flicker or scroll or does not even work.

Not working example: https://smartslider3.com/bugs/firefox/blurfixed/test.html

Works, but flickers when you scroll(set a small window height to be able to scroll): https://smartslider3.com/bugs/firefox/blurfixed/



Expected results:

It should work without flickering.
Also it is very choppy in iframe when you scroll: https://jsfiddle.net/eqqdssvj/1/
Component: Untriaged → Layout
Product: Firefox → Core
Component: Layout → Layout: Web Painting
Keywords: testcase
I can't reproduce any flickering, but I do see the background scrolling (and then eventually jumping back into place).

The latter part is going to be fixed by bug 1300864
Depends on: 1300864
I can confirm this in latest Developer Edition:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:58.0) Gecko/20100101 Firefox/58.0
Build ID: 20171211020921

The background stays in place until you click anywhere in the page to make it "refresh", then jumps back into proper position.
If you add background-size: cover; it really needs a click after the scroll to refresh.
Also in the latest Nightly with Build ID: 20171218100313 - this seems to be resolved besides that when you scroll the page you can still see the jumping effect. I'll post a video a little bit later with url to the live test site.
(In reply to newkind from comment #5)
> Also in the latest Nightly with Build ID: 20171218100313 - this seems to be
> resolved 

Yes, due to bug 1300864 being fixed. That fix hasn't made it to Developer Edition yet, which is why you're seeing it on Nightly only.

> besides that when you scroll the page you can still see the jumping
> effect.

We are aware of that. See bug 1404218 comment 12 for further plans to address that.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Priority: -- → P2
(In reply to roland from comment #0)
> Works, but flickers when you scroll(set a small window height to be able to
> scroll): https://smartslider3.com/bugs/firefox/blurfixed/

Is this test page still expected to work? I get TypeErrors in the console when I try to click on any of the options.
Flags: needinfo?(roland)
You can see the issue here : http://demo.rockettheme.com/live/joomla/fluent/ on the top of the page below the "F" logo.
:Botond The page works fine for me and I do not see any TypeErrors you mentioned.Just checked with Firefox 57.0.4 
https://smartslider3.com/bugs/firefox/blurfixed/

Here is a JSfiddle with the bug: https://jsfiddle.net/ff9d2u3v/2/ For this case only the first image relevant as that is the one with background-attachment: fixed.

Another example which does not flicker instead renders with 1 sec delay after you scroll: https://jsfiddle.net/xsbn7jbm/

See my previous comment.

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

Apologies for overlooking the previous comment.

(In reply to Soós Roland from comment #9)

:Botond The page works fine for me and I do not see any TypeErrors you
mentioned.Just checked with Firefox 57.0.4
https://smartslider3.com/bugs/firefox/blurfixed/

I do still get a TypeError. This is what is printed in the Console:

TypeError: n2(...).offset(...) is undefined [Learn More]    blurfixed:227:33
element      https://smartslider3.com/bugs/firefox/blurfixed/:227:33
onclick      https://smartslider3.com/bugs/firefox/blurfixed/:1:1

Here is a JSfiddle with the bug: https://jsfiddle.net/ff9d2u3v/2/ For this
case only the first image relevant as that is the one with
background-attachment: fixed.

Another example which does not flicker instead renders with 1 sec delay
after you scroll: https://jsfiddle.net/xsbn7jbm/

These are other examples where bug 1300864 has helped, but has not solved the problem completely, as described in bug 1404218 comment 12. I'm going to mark this bug as dependent on bug 1404218 which tracks further improvements in this area.

Depends on: 1404218
Flags: needinfo?(botond)

By the way, both fiddles behave perfectly in Firefox Nightly with WebRender enabled, so if that's an option for you, it's an easy fix.

You are right. It seems this issue haven been fixed.

Based on some profiling done this week, the reason the examples from comment 9 still exhibit the bug despite the intervention made in bug 1300864, is that blurs are really slow to compute on the CPU, and so the page cannot be painted within the frame budget. The intervention in bug 1300864 only fixed the problem for pages that can be painted within the frame budget.

So, the options here are:

  • Switch to GPU rendering (WebRender). This is being actively worked on, and is shipping on Windows with qualified graphics cards in Firefox 67.
  • Trade off the jumpiness caused by the slow painting time, to scrolling jank, by disabling asynchronous scrolling (option 3 from bug 1404218 comment 12). You can see what this looks like by setting the pref layers.async-pan-zoom.enabled to false in about:config. I'm open to input on whether that would be better or worse than the current behaviour.
  • Try to optimize the code to compute blurs on the CPU. Markus says this may be possible, but the value proposition is dubious given our pivot to GPU-based rendering.

Instead of applying blur over and over for every page scroll, why don't you just simply blur it once at initial render (and for every other action which affect the the image ex.: background-size:cover + size change) and reuse that blurred resource like you would with a simple image at page scroll?

In more typical cases, there is scrolled content which moves relative to the fixed background when you scroll, and the blur applies to their combination, and so needs to be recomputed on every frame.

We could probably detect the special case where there is no scrolled content, and avoid re-blurring on every frame in that case, but would that apply in your real-world use cases?

When the scrolled content and the background image are on a different layer with same blur, they looks identical when they are on the same layer.

Left is the single layer.
Right has a div in the background with the blurred image. And before that there is another div with the blurred text.
https://jsfiddle.net/1wsLmxbq/

No, the two are not equivalent. blur(over(A, B)) is, in general, different from over(blur(A), blur(B)). Here's an example: https://jsfiddle.net/pxLastb4/

The other factor that makes it impossible to cache the blurred rendering in the general case is the rectangle clip: The rectangle in which the fixed background is displayed moves during scrolling. The blur is applied outside of that rectangle clip. So, as the rectangle moves, the pixels around the shifted edges of the rectangle would need to be recomputed.

As the page author, if you want to express the fact that the blur should stay constant during scrolling, please use position:fixed and put your blur effect inside the fixed element. If you need a "moving window" effect, and you want that windowing clip to be applied outside of the blur, then you can use the properties "clip" or "clip-path" on a scrolled element to apply a scrolled clip to the position:fixed element. There's some example code for this in this stackoverflow answer.

See Also: → 1564071
You need to log in before you can comment on or make changes to this bug.