在html5流行泛滥的今天,作为一个web前端,你应该已经写过了无数的动画效果,你或许也在你的css3动画中加上了translate3d,使得动画流畅,但究竟这个为什么能使动画流畅呢,还有其他的东西能影响到动画的性能,或者说网页渲染的性能呢?
下面的内容将介绍页面渲染过程对性能是如何影响性能的:
内容基于 WebKit,更准确的说,是 WebKit 的 Chromium 分支,不过其他浏览器大体一致
一.一个html文档,从解析到屏幕
一个html文档从解析到渲染到屏幕,大致上有以下几步:
- html文档生成DOM树
- CSS代码转化成CSSOM
- DOM+CSSOM生成渲染树
- 根据渲染树上节点的位置大小等信息进行布局(layout)
- 将布局绘制到bitmap上
- bitmap传输至GPU然后绘制到屏幕
这个过程我们可以用chrome开发者工具清楚的看到:
不过注意想要看到上图所示的瀑布流,需要取消帧模式和事件模式:
浏览器所做的这些操作都要耗费时间,所以做的越少,性能越好,前3步我们是没办法做改变的.但页面解析完毕呈现在屏幕上后,后面的3个操作会因为某些操作而被触发,例如动画,而且触发越靠前的操作,浏览器需要做的越多,因为一旦触发一个步骤,后面的步骤都要再做一遍.因此我们可以做的就是从后面三个步骤入手,优化页面的性能.
二.layout,paint,composite
我们首先得了解layout,paint,composite的触发条件有哪些
layout
改变width/height/padding/margin/left/top等有关位置和大小的空间样式
改变上面的样式后,再读取offsetTop/scrollTop/clientTop等位置大小信息
paint
改变color/box-shadow/background/outline等有关表现的样式
composite
改变opacity/z-index等
所以,要提高网页渲染性能,我们首先可以尽量减少这些触发条件的出现,即使出现,也要尽量降低触发频率.现代浏览器会只能得将元素样式变动尽量一次执行,减少重复渲染.但是,如果我们像下面这样写,就会出现重复重排:
|
|
上面代码第一行对div.style.left进行改变,后续进行一次读操作触发一次重排以获取最新offsetTop,最后再改变div.style.top,触发又一次重排
所以我们要尽量将读写操作写在一起:
|
|
那么,我们还有其他方法吗,例如采用不触发layout和paint的方法.答案是可以的,那就是利用硬件加速.
三.硬件加速
所谓的硬件加速,就是通过生成一个特殊的GraphicsLayer层,让元素的渲染都在层中进行,而对元素的某些css操作并不会引起重排或重绘,这些css操作主要是transform等css3变换.硬件加速主要也应用在相关的css3动画中.
其原理是:
- dom解析时在某些条件下生成GraphicsLayer,每个层将独立的绘制进bitmap中
- bitmap传输到GPU作为texture渲染,并存储起来
- 特定css属性的变化,可以让层不用重新paint,而直接通过GPU中的textrue进行重新复合生成最终的屏幕图像,达到加速目的
从上面我们可以得知,加速的奥秘就在于不必让CPU进行重绘或重排,而将工作分配给了GPU;并且没有了重绘,bitmap传输到GPU的步骤也节省了.
而触发GraphicsLayer生成的条件之一就是使用translate3d,具体来说有以下一些条件:
- 3D 或透视变换(perspective transform) CSS 属性
- 使用加速视频解码的 video 元素
- 拥有 3D (WebGL) 上下文或加速的 2D 上下文的 canvas 元素
- 混合插件(如 Flash)
- 对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素
- 拥有加速 CSS 过滤器的元素
- 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
- 元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
注意的是,硬件加速不能滥用,上面所说的z-index较低的触发条件就可能是一个坑,参见:大神分享
以上是文章全部内容
参考连接:
http://melonh.com/sharing/slides.html?file=high_performance_animation#/
http://www.html5rocks.com/zh/tutorials/speed/high-performance-animations/
http://www.ruanyifeng.com/blog/2015/09/web-page-performance-in-depth.html

