使用will-change提升动画性能

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

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

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

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";
}
如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注