使用will-change提升动画性能

该文章发布于 ,归类于 未分类。

在之前制作动画效果时,一般使用transform: translateZ(0)来强制使用GPU进行加速。但是,可能这个动画并没有使用z轴的变化效果,所以,这样通常也被看做是一种hack的写法。

css3提供了一个新的属性will-change,用来告诉浏览器,某些元素将要发生变化了,让浏览器提前做好优化的准备。

首先,这个属性的兼容是这个样子的。

它有如下这些取值

auto
表示没有特别指定哪些属性会变化,浏览器需要自己去猜,然后使用浏览器经常使用的一些常规方法优化。
<animateable-feature> 可以是以下值:

scroll-position
表示开发者希望在不久后改变滚动条的位置或者使之产生动画。
contents
表示开发者希望在不久后改变元素内容中的某些东西,或者使它们产生动画。

<custom-ident>
表示开发者希望在不久后改变指定的属性名或者使之产生动画。如果属性名是简写,则代表所有与之对应的简写或者全写的属性。

所以,在某些要进行的动画的元素上,可以添加一条该属性来优化动画效果,例如使用transform来进行缩放变换。

.animate-scale {
    transform: scale(1.2);
    transition: transform ease-in-out 0.25s;
    will-change: transform;
}

.animated {
    transform: scale(1);
}

虽然,按照上面这样写可以达到优化动画的效果,但是同时也影响了页面的性能,我们只需要在元素需要进行动画的时候,为其附加上will-change属性,在动画结束后删除掉即可。所以,此处GPU一直在准备着.animate-scale的元素的动画优化,那么,如果过多地滥用该属性的话,有可能会适得其反。

在vue中使用transition进行动画时,正好可以使用到这个属性来进行加速。

.animate-scale-enter, .animate-scale-leave-to {
    transform: scale(1.2);
}

.animate-scale-enter-active, .animate-scale-leave-to {
    transition: transform ease-in-out 0.25s;
    will-change: transform;
}

此处,在动画的过程中使用will-changetransform进行加速,在动画结束后,删除掉该动画变换样式。

同时,MDN上也有一个类似的例子,不再赘述。

var el = document.getElementById('element');

// 当鼠标移动到该元素上时给该元素设置 will-change 属性
el.addEventListener('mouseenter', hintBrowser);
// 当 CSS 动画结束后清除 will-change 属性
el.addEventListener('animationEnd', removeHint);

function hintBrowser() {
  // 填写上那些你知道的,会在 CSS 动画中发生改变的 CSS 属性名们
  this.style.willChange = 'transform, opacity';
}

function removeHint() {
  this.style.willChange = 'auto';
}

相关文章