I spent some time on searching how will-change
property works and how we use it. I hope, it will be useful summary. Thanks everybody for answers.
1. Layers Hack / Null Transform Hack
In 'ancient times' (like 2 years ago) somebody discovered that you can draw your CSS animation faster.
How does it work?
If you add transform: translateZ(0)
to a css selector, it will force a browser to move the element with this selector to the new compositor layer. What is more, it will increase performance (in most situations, use powers of GPU instead CPU) read more here.
2. Bye Bye hacks, welcome "will-change:"
Probably, it's too early to say bye bye to Layer Hack, but this time will come shortly.
The new property will change
appeared in specs of CSS and will be a great successor of layer hack.
3. Browser support
For now, it's available in Chrome and Opera and partially supported by Firefox as well.
4. How to use it properly
Don’t use will-change anywhere in your CSS until after you will
complete implementing your animations. Only then should you go back to
your CSS and apply will-change. More
This is probably the most valuable advice that you can get.
There is no point to use it straight before an action begins by e.g. adding it to the :hover
state of a selector. Because browser will not have required time to prepare optimization before change occurrence. Browser will need approx. 200ms to apply optimization, so for example it is better to add will-change
to a element when a parent element is on hover state. More
Example:
.parent:hover .change{
will-change: opacity;
}
.change:hover{
opacity: .5;
}
You need to use it really sparingly. If you want to optimize everything, the results will be opposite than expected ones. will-change
forces browser to keep optimization turned on and reserve resources like memory for changes in the future which may never happen. It is recommended to turn off will-change
afterwards, when it is not necessary anymore e.g. when the animation is finished.
You can do it easily using JavaScript document.getElementById('my_element_id').style.willChange = off;