top | item 7872110

Everything You Need to Know About the CSS will-change Property

176 points| robin_reala | 11 years ago |dev.opera.com | reply

62 comments

order
[+] Steuard|11 years ago|reply
I hadn't heard about this before; I'm clearly out of the loop these days. With buy-in from smart people at Webkit and Mozilla, I've got to assume that it really will be an improvement over the status quo.

But, boy, it feels awkward at first sight. To my eye, it's weird to see what is essentially a low-level optimization instruction as part of CSS (which is usually all about presentation rather than implementation). Also, the article makes it clear that there are a lot of ways that people could mistakenly use this property in unhelpful ways. And I'm still not entirely clear on what they mean by "It’s not possible to remove will-change if it is declared in the style sheet": is this really a CSS property that can be turned on without scripting but never turned off without it? That makes me uncomfortable.

So why isn't this a case where we just need browsers to get smarter? In the same sense that an optimizing compiler can in most cases produce better performance than a human writing machine code by hand realistically could, can't we expect browsers to gradually get better and better at spotting these rendering optimizations? (To take an example from the article, couldn't the browser recognize that there's a transform rule for :active and automatically enable something equivalent to will-change for :hover itself?)

[+] bgirard|11 years ago|reply
I made the original proposal for will-change on Mozilla' behalf. I agree with your concerns, we've had them since 2010 and kept pushing back on proposing this. But with HiDPI mobile and 4k desktop it's really difficult without it.

It is nearly impossible to predict changes that some page do in perfectly reasonable ways, especially for changes triggered from Javascript. It's true that in some cases a will-change can be inferred from the style sheet but there are still too many changes triggered from JS events. You wont lose any performance by not using will-change and we will continue improving how we infer them. Once an element is declared as will-change the browser will be able to weight the hint and the platform specific costs of various possible optimization like layerizing the element and ignore it if it isn't suitable for the device.

If we can't predict the change then we're left trying to be ready to change a new element within one vsync interval to avoid any latency. This is fine if you're dealing with a small element but large elements like a fullscreen CSS page flip triggered from JS is going to be nearly impossible to perform without a frame or more of latency.

In the case of HiDPI mobile you typically have 2 millions pixels (8 MB) to deal with on a 1GB/s memory bus with a frame time of 16ms. That means that if you touch 16 MB, or twice the size of the screen, then you have zero chance to perform that change without introducing delays. And this is without even considering the CPU/GPU cost require to perform the change. The situation may also get tough on 4k desktop without a discrete GPU if you have 31MBs per fullscreen surface on a 10GB/sec bus.

These are all theoretical throughput maximums. In practice on Android and Firefox OS where a style change occurs on large and complex elements where rasterization is difficult you can't use SIMD to rasterize the page at memory bandwidth speeds, you instead are bottlenecked on rasterizing complicated content. It's typical to see these complex change cause 100ms latency. Once the rasterization is made then the animations can continue smoothly but you're still left with animations skipping at the beginning.

[+] Steuard|11 years ago|reply
Heck, the browser could even do a lot of things that wouldn't even be an option via CSS. For a transition set to occur on :hover, the article suggests that a human might want to add a will-change attribute to :hover on the containing element (which could potentially be quite large). But the browser could in principle trigger the equivalent will-change optimizations just for a small buffer region surrounding the element with the transition. Or if you wanted to be really ambitious, the browser could even trigger only when the mouse is nearby and actually moving toward that element. I couldn't do any of that via CSS (and I shouldn't have to be the one to do it via JS).
[+] dmmalam|11 years ago|reply
Should'nt this be something that the browser should auto-optimise with a smart renderer?

In the example given with the element:hover and element:active, it would trivial to parse all possible CSS transforms. Then live profiling of the page would give data on the likelihood of particular transforms. The browser could then optimise as necessary given hardware limitations and current resource constraints. Even transforms added via javascript or onhover would be caught via live profiling.

The given use case of stopping flickering when a layer is created should be treated as a bug.

This feels hacky, and likely to be used erroneously or abused - at which point browser will be forced to smartly ignore leaving us with yet more cruft. Performance tuning is a fine art, and browser is in a better position to do it vs your average web developer.

[+] ender7|11 years ago|reply
Style properties such as transforms can be changed at runtime by JavaScript (and frequently are for things like dragging operations). There is no practical way for the profiler to detect which styles of which elements your JavaScript will attempt to modify.
[+] wvenable|11 years ago|reply
Live profiling is not the panacea you seem to think it is. The purpose of this is to allow the browser to chose the optimal layout for an element before that layout is required. In other words, before any code you might live profile is actually run. That's the point.
[+] Swizec|11 years ago|reply
I'm not sure why, but your comment reminds me a lot of all the "Well, if you just had a sufficiently smart compiler ..." arguments that people make.
[+] troels|11 years ago|reply
My thoughts as well. This is an implementation optimisation - It seems wrong to put this kind of stuff into user space. Especially as it seems like something that should be possible to solve with a smarter rendering engine.
[+] bgirard|11 years ago|reply
I think 'flicker' is the wrong word. What the author means is delay/latency/jank.

'Profiling' or inferring the animation is what engine already do. The problem is as an author you're not getting predictable performance. Imagine making a tweak and then rendering engine X or Y no longer infers the animation and now you have a large performance regression.

[+] nostrademons|11 years ago|reply
Live profiling wouldn't work for social reasons. When a frontend engineer demos to his executive, or a startup CEO displays a MVP to a prospective customer, they usually get a link on a cold browser, and if the transition is janky, they're like "Nope, don't want." So every frontend engineer worth his salt will continue to use the null transform hack to keep things smooth even on the initial transition.

I was one of the Blink team's initial "reference customers" within Google for this, and we were pretty adamant that if there's any jank at all between when the user taps on a link and when the transition starts firing, it was a no-go for us. We've had launches canceled because they added to user-perceived latency instead of subtracting from it.

[+] Pxtl|11 years ago|reply
I would hope that the browser would parse all CSS transforms and then use this particular attribute just for Javascript-based transforms.
[+] timothya|11 years ago|reply
A lot of people are complaining about putting this into CSS, but I think that people are forgetting that using null transform hacks[0] is already the status quo for making animated elements more performant.

What this property does is lets us continue doing the same thing, but in a way that the intent is clear ("I'm using this property to make the animation on this element more performant" vs. "I want to add a transform that does nothing"). Furthermore, it lets the browser decide if it wants to add any optimization, and it can decide which sort of optimization is best.

While it would be nice if we didn't have to do this hinting at all, the fact of the matter is that it's hard for the browser to predict what will happen on the page in the future, and we're already having to do this (just in the cryptic null transform way), so it's nice that the web platform is letting us do it in a standardized way that communicates our intent clearly.

[0]: http://aerotwist.com/blog/on-translate3d-and-layer-creation-...

[+] untog|11 years ago|reply
I feel like this is a great example of the... continuing OK-ness of the web as a platform. It feels hacky, but it's considerably less hacky than using unrelated CSS properties, so it's progress and I'm happy with that.
[+] eli|11 years ago|reply
What would be an example of a non hacky way of hinting to the browser which properties are likely to change?
[+] gren|11 years ago|reply
I'm a bit skeptical about this new property.

In this basic example,

    .element:hover {
	will-change: transform;
    }
    .element:active {
	transform: rotateY(180deg);
    }
it seems very predictable. I don't get why the browser couldn't guess (with some heuristics) what to prepare.

Also I feel we will misuse this feature and tend to make the performance worth than if the browser would detect what are the "will-change"s.

[+] untog|11 years ago|reply
Which works fine in a CSS-only environment. But a lot of the time these properties are being set in JS, which is going to be very difficult to predict.
[+] ultimatedelman|11 years ago|reply
While it may be functionally great, it just smells wrong to have a CSS property that you're pretty much only supposed to set via JS that you're supposed to remove after you've set it.
[+] pothibo|11 years ago|reply
I don't know why, but to me it feels like that will-change property should have been associated to the HTML, not CSS.

    <section class="animatable" will-change='transition'></section>

    section.animatable:active {
     // someanimation
    }
The above makes more sense to me than the following:

    section.animatable {
      will-change: 'transition';
      &.animating {
        // Some animation
      }
    }
[+] danabramov|11 years ago|reply
I don't understand why people complain about this. It makes perfect sense: when you change your CSS (maybe adding `opacity` to `transform: translate`), you will notice this property and remember to update it. If it stays in your HTML or JS, you (or whoever changes CSS later) won't keep it up-to-date and the optimization hint will be wrong (which can hurt performance).
[+] KyleLH|11 years ago|reply
I haven't done much with CSS transformations, but I really like this change and think it's a step in the right direction. So much of the web development I've done has involved doing weird hacks to achieve the desired result, and I think that making will-change a valid attribute will help make things more clear. Hopefully this trent will continue.
[+] jhherren|11 years ago|reply
Putting performance optimization hints in my presentation code feels wrong. I think I'd use a separate css file for will-change.
[+] talmand|11 years ago|reply
By what I'm reading you shouldn't have the property in a style sheet at all. The author implies that every usage of the property requires resources that are never released as long as the property is still active. The property in a style sheet will mean that the resources are never released.

Thus, the suggestion to use the property through javascript so that it can be applied and then removed. That just seems totally weird to me.

[+] frik|11 years ago|reply

  only WebKit and Firefox Nightly builds have implemented [it] 
  [...] There is also an intent to ship in Blink too.
(Opera is based on Chromium that uses the WebKit fork "Blink")

Offtopic: first time in years, I see the opera.com website. There was a lot of useful information in their blog posts, when they still worked on their own browser engine.

[+] IgorPartola|11 years ago|reply
The real question is when will mobile Safari, mobile Firefox, and mobile Chrome support this?
[+] wildpeaks|11 years ago|reply
Small gotcha for people who have been keeping an eye on that from afar for a while: make sure to notice the property is now called "will-change", not "will-animate" anymore.
[+] general_failure|11 years ago|reply
While I understand the need for the property, it is absurd to put this in a style sheet document :( oh well I have mostly given up on this doc/style/code separation anyway
[+] exo762|11 years ago|reply
Mostly technical article about CSS opening with explanation of what CPU and GPU are and where they are located. I'm very surprised that those two terms even need explanation.
[+] gpvos|11 years ago|reply
Acceleration using the GPU is what will-change is all about.

Also, especially among web developers there are many people who barely know what they are doing, so it's a good idea to comprehensively cover the context (I know it helped me, since I'm mostly a back-end developer who does some front-end on the side).

[+] danatkinson|11 years ago|reply
Is there a test suite/page for the will-change property in order to gauge vendor compliance?
[+] tempodox|11 years ago|reply
I love this article. It is well written and it even has a date. Thanks :)
[+] EGreg|11 years ago|reply
Is it a commentary on the state of affairs that I was more impressed to see this written by a Female Lebanese web developer than I was at the content?