使用translateZ(0)提升性能的原理是什么?

很多文章中都写到使用tanslateZ可以利用gpu加速,提高浏览器渲染的性能;一些文章中说原理是因为使用translateZ的元素会单独占据一个渲染层;这样减小了元素变动时,浏览器的重新绘制的区域。

但是实际上使用translate和opacity的元素就会单独占据一个渲染层,所以使用translateZ做硬件加速的真实原理是什么?

阅读 24.3k
5 个回答

楼上的回答都没有解答自己的疑惑,就去研究了一下;并写了一篇文章,https://segmentfault.com/a/11...;对动画优化有兴趣的童鞋可以看看。

这个问题是因为使用transform和opacity做CSS动画的时候,会将元素提升为一个复合层;而使用js操作css属性做动画时,必须使用translateZ或will-change才能将元素强行提升至一个复合层。

元素本身使用transform和opacity做CSS动画的时候,会提前告诉GPU动画如何开始和结束及所需要的指令;所以会创建一个复合层(渲染层),并把页面所有的复合层发送给GPU;作为图像缓存,然后动画的发生仅仅是复合层间相对移动。

而使用js做动画,js必须在动画的每一帧计算元素的状态;发送给GPU,但不会将元素提升至一个复合层;所以想让元素提升至一个复合层,必须使用translateZ或will-change: transform, opacity。

可以做一个小实验,当元素使用css动画时:

<div class="bg-change"></div>
<style>
.bg-change {
  width: 100px;
  height: 100px;
  background: red;
  transition: transform 20s;
}
.bg-change:hover{
  transform: translateX(1000px);
}
</style>

然后我们执行动画,在控制台中的layers可以看到;会有两个layer:

clipboard.png

当我们使用js动画时:

<div class="bg-change"></div>
<style>
.bg-change {
  width: 100px;
  height: 100px;
  background: red;
}
</style>
<sctipt>
var bg = document.querySelector('.bg-change');
var distance = 0;
requestAnimationFrame(function animate(){
  bg.style.transform = 'translateX(' + ++distance + 'px) translateZ(0)';
  requestAnimationFrame(animate);
})
</script>

然后在控制台,可以看到只有一个layer:

clipboard.png

当我们改变上述代码,添加translateZ(0)的时候;可以看到又有两个layer了:

bg.style.transform = 'translateX(' + ++distance + 'px) translateZ(0)';

clipboard.png

不使用 translateZ 的话,一个平面,只有 x 和 y 轴,你能做 3D 动画吗?

translateZ变成3d效果,走GPU渲染。
CSS3开启GPU硬件加速
然后chrome输入chrome://flags/
能看到这么一句“允许使用 GPU 执行 2D 画布渲染(而非使用软件渲染)”。说明2d是软件渲染的。

可以开启gpu渲染,也就是硬件加速。
这样也有缺点就是耗电和发热问题。
同样的canvas也会开启gpu渲染

推荐问题
宣传栏