前情回顾:
上回我们说到我们推荐了css3动画(动画浅析)。那我们这次来看一下css3的动画原理,以及如何开启硬件加速(GPU加速,3D加速)。
在加速之前,我们先熟悉几个概念:
帧:帧——就是影像动画中最小单位的单幅影像画面,相当于电影胶片上的每一格镜头。动画其实是页面一帧一帧刷新和渲染页面的过程,帧是动画的最小单位。
帧率:帧率——fps(frame per second),一秒内渲染的的帧数。当每秒渲染的帧数小于40的时候,也就是帧率<40fps的时候,在网页上就会感觉到卡顿。不同的行业对帧率的要求也是不一样的,比如电影在24fps的时候就感觉很流畅,而游戏就要求50-60fps。
GPU:Graphics Processing Unit(图像处理单元),在图像,音频,视频处理,3d渲染和图像处理方面的优越性要超过CPU。
熟悉了概念之后,我们看下浏览器是怎么处理动画的,知己知彼,百战不殆。
要说浏览器处理动画,总共分几步?哈哈哈,不自觉想到宋丹丹老师。好了,回来看浏览器吧:
我们来细分一下每一步做了什么:
1)获取dom:这个没说的,就是获得我们所有的dom树,因为要渲染了嘛,浏览器总得知道是个啥东西。
2)分割图层:这一步,浏览器根据z-index,和脱离了原来dom层的dom解构进行分层。
3)计算样式:分解图层完毕后,将所有的图层批量进行样式计算。这里有些属性是CPU去计算的,有些属性是GPU去计算的,具体哪些,请看下文。
4)reflow-relayout-paint set up-repaint:这一系列过程其实是页面从回流到重绘发生的步骤,这也是为什么回流必然引起重绘,而重绘却不一定要回流的原因。
5)GPU:重绘后的“画布”交给GPU去处理。
6)组合布局:浏览器组合布局,然后页面就出现了。
加速原理:
重绘还是比较吃性能的,重绘次数越多,丢帧的几率也就越大,页面看起来就会越卡。所以,我们改变属性的时候,要从减少处理流程入手。
所谓的GPU加速,也是将属性交给GPU处理,GPU处理速度为什么比CPU快?一个是减少了浏览器处理流程,另外一点,和GPU的设计有很大的关系,GPU专为处理图像而生,内部的处理单元比CPU多很多,在处理多并发的时候比CPU有很大优势,CPU在逻辑运算方面比GPU要快,但处理多并发不如GPU。
哪些属性会触发重排(relayout)?
1)盒子模型相关属性:
* width * height * padding * margin * display * border-width * border * min-height(width) * max-height(width) 等等。
2)定位和浮动
* top * bottom * left * right * position * float * clear
3)改变节点内部文字结构
* text-align * overflow-y * font-weight * overflow * font-family * line-height * vertical-align * white-space * font-size
哪些属性会触发重绘(这个比较杂,就不做分类了):
* color * border-style * border-radius * visibility * text-decoration * background * background-image * background-position * background-repeat * background-size * outline-color * outline * outline-style * outline-width * box-shadow
如何加速?开启GPU(硬件,3d)加速
GPU(显卡的心脏)硬件加速(3d加速)。根本原因是创建了新的layer,属性改变直接由GPU处理,加快处理速度。
当浏览器监测到含有某个css属性或规则的时候,就会创建新的layer开启GPU加速,最常用的是3d转换(translate3d)。
所以,有一些属性的改变可以略过relayout,减少浏览器在动画运行时所需要做的工作,其原理也是创建了一个新的layer,这只是一个无害的语法糖。
GPU加速也是有缺点的,GPU使用会增加内存消耗,同时也会影响字体的抗锯齿效果,导致文本在动画期间会显得有些模糊。
1.开启GPU加速前后的处理流程对比。
拿改变组件高度为例,如果我们直接去改属性height,浏览器会这样处理:
如果我们改变transform,浏览器会这样处理:
transform属性会直接交给GPU处理,而height会触发relayout。所以,动画中尽量多的使用transform属性,会大幅提高动画性能。
2.什么情况下,浏览器会创建新的layer,开启GPU加速?
在webkit内核的浏览器中,如果有上述情况,则会创建一个独立的layer:
1)transform(3d转换)
2) video标签
3)混合插件(如 Flash)
4) isolation == isolate
5)opacity < 1
6)filter != normal
7)z-index != auto || 0 + 父元素display: flex|inline-flex
8) mix-blend-mode != normal
9)position == fixed || absolute
10)-webkit-overflow-scrolling == touch
11)will-change:指定可以形成新layer的元素。
其实,在css3中,最推荐的还是使用transform:translateZ(0);来创建一个新的layer,成本低,影响小。
除了GPU加速,还有一个比较好用的属性,可以告诉浏览器什么属性将会发生变化,让浏览器做好最佳处理:
will-change。
但好像,兼容性还是有些那啥的,至少IE目前是不支持的。
怎样,是不是感觉干货满满?那就给个赞嘛。