4

When using the will-change property to optimize a CSS keyframe based animation, should you set its property to animation or to the properties changed inside of the keyframe?

So, assuming this CSS:

@keyframes dropDown {
  0%   { opacity: 0; top: -100%; }
  100% { opacity: 1; top: 0; }
}

.element.trigger {
  animation: dropDown 1s;
}

Should I use will-change like this:

.element {
  will-change: animation;
}

Or like this:

.element {
  will-change: opacity, top;
}
Nils Kaspersson
  • 8,816
  • 3
  • 29
  • 30
  • @ralph.m What do you mean by "neither way"? I fail to see how the article answers my question. Would you mind elaborating? – Nils Kaspersson Jun 16 '14 at 09:33
  • If you still looking for answer you can read this thread: http://stackoverflow.com/questions/26907265/css-will-change-how-to-use-it-how-it-works – LJ Wadowski Nov 16 '14 at 17:13

2 Answers2

1

The short answer is, I'm not sure. :) The longer answer is, I expect this is going to be browser-dependent, at least in the near term, as browser developers chew on different implementations of the spec and decide on how to handle cases like you suggest.

However, my understanding on reading the spec, supplemented by the Opera blog, is that you would use individual properties like your second example:

.element {
  will-change: opacity, top;
}

Specifically, the section on custom-ident:

Indicates that the author expects to animate or change the property with the given name on the element in the near future. If the property given is a shorthand, it indicates the expectation for all the longhands the shorthand expands to.

Since animation is itself a shorthand property that expands to the various animation-related properties, I'd expect a better usage of will-change is to explicitly state which properties will be animated in an upcoming rule, to allow the rendering engine to be as targeted as possible about the work it's doing.

Palpatim
  • 9,074
  • 35
  • 43
  • The second example makes more sense to me as well, since `animation` is more of a trigger for change and not the actual change. But on the other hand, it would also make sense to inform the browser that it should prepare for a specific animation, although that's probably more of QoL than a feature. – Nils Kaspersson Jun 16 '14 at 15:29
1

There are a couple things going on here.

First off you need to only use will-change right before the animation and unset it right after: https://developers.google.com/web/fundamentals/performance/rendering/simplify-paint-complexity-and-reduce-paint-areas. This is best done in javascript. Leaving will-change in a style rule will cause the browser to render that element on a new layer forever (increasing the amount of memory your browser keeps on the page).

Also, try animating things with transform: translateY() instead of top. It's cheaper: https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

Here's a quick demo to show you how you might approach this:

https://codepen.io/newshorts/pen/RLPvZE?editors=1100

.box {
  width: 100px;
  height: 100px;
  border-radius: 20px;
  margin: 50px;
  animation-name: fadeUpIn;
  animation-duration: 2s;
  animation-fill-mode: forwards;
}

@keyframes fadeUpIn {
  from { 
    will-change: transform, opacity;
    transform: translateY(0%) translateZ(0);
    opacity: 0;
  }

  to { 
    will-change: unset;
    transform: translateY(-100%);
    opacity: 1; 
  }
}
newshorts
  • 1,057
  • 12
  • 12