Open Bug 1288216 Opened 8 years ago Updated 2 years ago

Animating an element into view using only a transform, should not cause a full repaint.

Categories

(Core :: Web Painting, defect, P3)

50 Branch
defect

Tracking

()

People

(Reporter: gordonrankin82, Unassigned)

References

Details

Attachments

(1 file)

Attached file example.html
User Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36

Steps to reproduce:

Animate any element (that has its own layer) in to, or out of view,  using css translate.


Actual results:

The element gets repainted.


Expected results:

Animating a transform of an element on it's own layer, should take place in the compositor, and should not require the element to be be repainted each time it is animated.

In the attached testcase, I have inserted a heavy duty SVG into the animating element in order to bump up the paint time to make it more visible, but the issue occurs even if the element simply contains text.

The testcase also shows bug 1275694 that is filed separately.
As an example of how this is causing problems, in our app, we have several elements, all containing high res images, SVG icons and other content.  These elements are contained in an overflow:hidden parent and get transformed out of view.  This causes a huge paint as each element gets re-rendered.  This long paint takes 100-250ms on the latest nightly and around half that time in 47 stable. (Although surely these elements should not be getting repainted at all).

No other browser suffers from these long repaints.
Blocks: 1275694
Component: Untriaged → Layout
Flags: needinfo?(matt.woodrow)
Product: Firefox → Core
We don't repaint during the animation, it's done on the compositor as you say.

We only repaint once the content has been static for 250ms, at which point we flatten it into the background which requires a repaint.

You should use will-change:transform if you want us to retain content separately for a transform that isn't currently moving.
Flags: needinfo?(matt.woodrow)
(In reply to Matt Woodrow (:mattwoodrow) from comment #2)
> We only repaint once the content has been static for 250ms, at which point
> we flatten it into the background which requires a repaint.

I see, that makes sense.

> You should use will-change:transform if you want us to retain content
> separately for a transform that isn't currently moving.

If I add will-change:transform to the element in my testcase, I still get the paint.  So I guess, it still gets flattened and an unnecessary paint occurs even though I am expecting to animate the element again.  Is this correct?  If so, is this desirable behavior?  Should will-change not prevent the flattening paint from occurring?
In the attached testcase, the animated element has a larger size than the viewport (unless you have a really big window), so we disable full layerization. We don't go as far as to merge the painted content with the background, but we throw away any content that's offscreen, so it will repaint in pieces as it gets moved back onscreen. If you resize the SVG to something smaller, then will-change:transform will do what you want.
This size limitation ("no bigger than the viewport") is something we apply regardless of will-change, whenever you have a transform animation.

We also have abuse detection specific to will-change. If you apply it on too many elements, or on elements that are too large in total, we will stop respecting will-change for the whole document and print a warning to the error console. This is to avoid wasting too much memory.

We are still tweaking the heuristics. I'd be interested to see your real world use case in a non-reduced form, and whether you see a warning about will-change in the console when you apply will-change on your site.
(In reply to Markus Stange [:mstange] from comment #4)

Thanks Markus.  That's cleared things up for me.  

> We are still tweaking the heuristics. I'd be interested to see your real
> world use case in a non-reduced form, and whether you see a warning about
> will-change in the console when you apply will-change on your site.

I'll put together a detailed testcase tomorrow, showing the exact issue we are facing.  

To give you an idea, we are essentially recreating certain native mobile style, state transitions for the web.  In this specific case, imagine opening an app on an iPhone.  The surrounding icons explode/expand outwards out of view as the selected app enlarges to fill the screen.  They are scaled around a center of enlargement, centered on the selected application/icon.  Android has very similar transitions.

In this case, the elements surrounding the selected one, all get transformed out of view. (whether we scale them around an origin, or simply translate them)  Which triggers the situation you have described.

Anyway, i'll put together a less reduced testcase for you tomorrow, which should show you exactly what I mean.  Thanks again.
Priority: -- → P3
Should this still be UNCONFIRMED?  It's very easily reproducible and causes the browser to be unusable.

Example: https://overwatch.reddit.com

CodePen of the above animation: https://codepen.io/mmolad/pen/wpvYLK
Flags: needinfo?(bugs)
It's definitely confirmed, just not something we've had time to fix yet unfortunately.

We want pages like this to be fast, but we also want to prevent websites (particularly on mobile) from being able to use excessive amounts of memory.

Jamie, this has some interesting testcases if you're planning on looking at the transform heuristics again.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(bugs)
Component: Layout → Layout: Web Painting
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: