前言
在正片开始前,请允许我先抛一块砖
👇
使用translate改变位置和使用position改变位置有什么区别?
直接说答案吧:
translate
是transform
的一个值改变
transform
并不会触发回流和重绘,只会触发复合
。但改变position
会直接导致回流和重绘。而且transform
由GPU
创建图层,position
由CPU
创建图层,因此从的性能上而言,使用translate
来移动对象是一个更好的选择
上面的回答又引伸出了两个问题:
transform
只触发复合
,而不触发回流
和重绘
?- 硬件加速能提高性能?
transform
只触发复合
,而不触发回流
和重绘
这里出现了一个相对偏门一点的词 -- 复合
。那这个复合
到底是什么东西,还得先从浏览器的渲染流程说起(以下内容参考:层叠上下文 渲染图层 复合图层(硬件加速)区别与联系,并且讲述主体为chrome
浏览器)
渲染图层(Render Layer)与复合图层(Graphics Layer)关系
先来看一下这张图片👇
这是chrome
的简单渲染流程关系,可以看到在Layer trees
部分中,Render Layer
和Graphics Layer
是两个独立的流程。简单的理解就是,拥有层叠上下文属性的元素会生成一个新的层叠上下文对象
,每个层叠上下文对象都是一个渲染图层,渲染图层与复合图层是不同的概念,渲染图层
更像是一个纯二维
的概念,无论其怎么层叠覆盖最终都归依于根层叠上下文。而复合图层
则完全脱离根层叠上下文,相当于开辟新的位面
。
那么来简单概括一下这两个图层:
渲染图层
是页面普通的文档流,虽然可以通过浮动、绝对定位等方法脱离文档流,但仍属于根层叠上下文
,共用一个绘图上下文对象
复合图层
每一层都会由系统独立分配资源
,并形成一个独立的绘图上下文对象
,而且脱离文档流,因此不会引起渲染图层
中的回流或重绘
transform
真的只触发复合
吗
了解了复合
之后,让我们来实践一下,看看transform
是否真的只触发复合
,而没有回流和重绘
浅创建一个一直执行transform
动画的盒子,然后观察控制台的绘制指令
有没有增加
<style>
@keyframes move {
0% {
transform: translateX(0);
}
100% {
transform: translateX(1000px);
}
}
#composited {
width: 200px;
height: 200px;
background: red;
position: absolute;
left: 0;
top: 0;
animation: move 10s infinite;
}
</style>
<div id="composited" class="both">composited</div>
看一下控制台的绘制指令
有没有变化👇
可以发现,即使让系统重新计算绘制指令
也没有新的增加,由此可以得出结论,transform
确实没有引起回流和重绘
硬件加速能提高性能?
在上文中提到过,translate
是由GPU
控制的一个独立的图层,因此不会引起回流和重绘,那么是否translate
的性能就优于position
呢?别着急,让我们先从GPU
和CPU
的区别开始讲起
CPU
和GPU
的区别
CPU
是计算机的大脑,我们写的程序最终会通过CPU
指令来控制计算机执行,它会对指令进行编码,然后通过逻辑电路
来执行该指令,执行的流程分成了多个阶段,执行完一个流程就是一个指令周期
,而CPU
就是不断地执行指令周期来完成各种任务。
GPU
是显卡的大脑,主要负责加速图形处理速度
,决定了显卡的档次和大部分功能,同时也是2D显卡
和3D显卡
的区别所在。2D显卡芯片
在处理3D图像和特效时需要CPU的协助,而3D显卡芯片
则集中在显示芯片中,也就是所谓的硬件加速
功能。
二者的主要区别就在于芯片内的缓存体系
和数字逻辑运算单元
的结构差异:
CPU
的核数不多,但胜在每个核都有足够大的缓存和数字逻辑运算单元,因此可以胜任很多复杂逻辑判断GPU
的核数远超CPU
,但每个核的缓存较小而且数字逻辑运算单元较为简单,因此常运用于计算多个节点运动的动画中
如何使用硬件加速
- 最常用的方式:
transform
、opcacity
will-change
属性<vedio>
、<iframe>
、<canvas>
等元素
硬件加速的注意事项
在使用硬件加速时,尽可能加上z-index
来防止浏览器给后续的元素重复创造复合层
它的原理是:
webkit CSS3中,如果一个元素添加了硬件加速,并且
z-index
的层级较低,那么层级高于或等于该元素,并且relative或absolute属性相同的元素会默认变为复合层渲染,处理不当则会极大地影响性能
硬件加速 OR NOT?
通过上面的比较可以发现,对于处理动画而言,似乎GPU
是个更好的选择,因为它帮助CPU
完成了部分的图形绘制工作,减轻了CPU
的负担
那么下面就通过实践看看GPU
是否真的减轻了CPU
的负担👇
还是刚才的例子,但是把盒子的数量增加到5个,分别通过transform
和positon
方式移动盒子,并在任务管理器中查看CPU的使用率
transform
👇维持在3%到6%之间
position
👇最高甚至达到11%
可以很明显地看到,使用transform
和postion
的CPU占用率
区别还是挺大的,由此也得出结论:使用GPU
确实可以减轻CPU
的负担
那么这是不是就意味着可以随意在项目中使用硬件加速来优化性能呢?NO NO NO~
内存
。如果GPU
加载了大量的纹理,那么就很容易发生内存过载的问题,尤其是移动端浏览器
GPU
渲染会影响文字的抗锯齿效果,在动画过程中文字可能会变得模糊不清
硬件加速虽好,可不要贪杯哦
结语
要是有任何写错或者需要求改的地方,恳请指出,感激不尽~