写在前面
- 说到优化是个很大话题,估计写本书也说不完。本文只针对前端动画的优化来浅述。
- 本文概念性的东西比较多(如:reflow、repaint),理解概念是前提。其中重排和重绘是两个重要概念(由于它们是致使卡顿的重要缘由,其中重排的成本比重绘高不少)。
重排
- 概念:即reflow,当咱们在某个元素上执行动画时,浏览器须要每一帧都检测是否有元素受到影响,并调整他们的大小,位置,一般这种调整都是联动的,咱们称为reflow。
- 触发重排的相关属性:
- 盒子模型相关属性会触发重布局
- width
- height
- padding
- margin
- display
- border-width
- border
- min-height
- 定位属性及浮动也会触发重布局
- top
- bottom
- left
- right
- position
- float
- 改变节点内部文字结构也会触发重布局
- text-align
- overflow-y
- font-weight
- overflow
- font-family
- line-height
- vertival-align
- white-space
- font-size
重绘
- 概念:即repaint,动画执行时,浏览器还须要监听元素的外观变化,一般是背景色,阴影,边框等可视元素,并进行重绘,咱们称为repaint。
- 触发重绘的相关属性:
- 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
浏览器是如何渲染DOM的
- 获取DOM后分割为多个图层
- 对每一个图层的节点计算样式结果(Recalculate style--样式重计算)
- 为每一个节点生成图形和位置(Layout--回流和重布局)
- 将每一个节点绘制填充到图层位图中(Paint Setup和Paint--重绘)
- 图层做为纹理上传至GPU
- 符合多个图层到页面上生成最终屏幕图像(Composite Layers–图层重组)
建立新的渲染层
建立新的渲染层,执行动画时,只须要GPU按照现有的位图,按照相应的变换在独立的渲染层中输出,而后再合并输出。这个过程并不须要主线程CPU的参与,这就是优化的核心点。css
建立新的渲染层的状况:前端
- 当一个元素位于HTML文档的最外层(元素)
- 当一个元素position不为initial,而且拥有一个z-index值(不为auto)
- 当一个元素被设置了opacity,transforms, filters, css-regions, paged media等属性。
- (固然还会有其余状况,具体可参考下面的参考连接)
JS动画和CSS3动画的比较
- js动画:优势是咱们能随时控制开始,暂停,中止。缺点是没办法像css这样优化,由于js动画是在主线程上跑的,容易卡顿丢帧。
- css3动画:优势是浏览器能够对动画进行优化。它必要时能够建立图层,而后在主线程以外运行。缺点是缺少强大的控制能力。
结论
- 咱们应该尽力避免使用会触发重布局和重绘的属性,以避免失帧。最好提早申明动画,这样能让浏览器提早对动画进行优化。
- 如今用来作动画的最好属性是以下几个:opacity、translate、rotate、scale,尽可能避免left/padding/background-position等。
- 若是须要JS执行动画,使用requestAnimationFrame,或者Velocity,避免使用jQuery动画,setTimeout,setInterval。
- 尽量的为产生动画的元素使用fixed或absolute的position。
- 使用3D硬件加速提高动画性能时,最好给元素增长一个z-index属性,人为干扰复合层的排序,能够有效减小chrome建立没必要要的复合层,提高渲染性能,移动端优化效果尤其明显。
- 然而并非全部浏览器默认都会开启GPU渲染,因此一般会用translate3d,translateZ,或者是opacity < 1等来强制开启。
参考连接css3