有时候想要进行性能优化时了解浏览器的渲染过程无疑是十分重要的。下面来看
首先介绍一下主流浏览器的渲染引擎:
IE:Trident
chrome:Blink
Safire:webkit
Firefox:Gecko
Opera:Blink
QQ浏览器/微信webview:X5/Blink
可能有很多会感到疑惑:chrome不是webkit么?其实Blink也算是webkit的一种升级吧,前缀还是不变的。
然后介绍一下渲染过程
1、DOM解析(与CSS解析同时进行):
把HTML文档解析成DOM树的过程;
在这之中:
*注意event:DOMContentLoaded完成的时间:它是在页面初始的HTMNL页面加载和解析之后,这这之前是没有样式表,图片,和子帧(subframes)完成加载的。注意和load的区别。这里可以参考原文档:
The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. A very different event load should be used only to detect a fully-loaded page. It is an incredibly popular mistake to use load where DOMContentLoaded would be much more appropriate, so be cautious.
其实去看渲染的时间线就会发现:load总是在pages show之前。DOMContentLoaded就很多情况了。不过在外联script时除了属性为async时都在js解析之后。
2、CSS 解析(与DOM解析同时进行):
把css代码解析为css规则的过程
*与script的执行互斥;在解析script时会直接停止DOM的解析(外联),内联时是在DOM解析的过程中编译script脚本。
3、DOM Tree:
这个就很明显了,由DOM解析之后形成的文档对象模型。
*注意display:none、<script></script>标签、注释都在DOM Tree中
4、Render Tree:
DOM Tree + CSS Rules = Render Tree
*每一个节点叫Render Object对象,包含了对象的宽高、位置、背景色、等样式信息。
*宽高和位置通过Layout计算的。
*display:none的元素不在Render Tree中,因为它在页面布局中是不存在的。visibility:hidden的元素只是隐藏所以在布局中是要有的,所以它存在于Render Tree中。
*float、absolute、fixed元素会脱离文档流也就是脱离当前的Render Tree,重新布局。
5、重排(Layout)/回流(reflow)
我觉得重拍就是重新布局的过程,计算宽高和位置啊,如何排列啊这种。
*当修改元素的位置、大小时可能会引起父集元素的位置和大小,或者影响周围元素的位置,从而导致重排。也就是重新进行页面的布局。
那如何避免重排呢:
*用transform做形变和位移。
*或通过绝对定位,脱离当前层叠上下文(即形成新的Render Layer)
6、Render Layer:
在某些条件下Render Tree中的节点会提升为Render Layer。生成Render Layer是将Render Tree上的某些节点提升到同一个Layer的过程。
*方便浏览器进行处理定位、页內滚动、裁剪、CSS Transform/OpCity/Animation/Filter、z-index排序
*生成Redner Layers之后会合并成一颗Layer Tree
*浏览器基于Layer Tree进行Paint
*有时可通过obsolete来避免重排
生成Render Layer的条件:
*根元素(HTML)
*有明确的定位属性(relative、fixed、static、absolute)
*透明的(opacity小于1)
*有CSS滤镜(filter)
*有CSS mask属性
*有CSS mi x-blend-mode属性(不为normal)
*有CSS transform属性(不为none)
*backface-visibility属性为hidden
*有CSS reflection属性
*有CSS column-count属性(不为auto)或者有CSS column-width属性(不为auto)
*当前有对于opacity、transform、filter、backdrop-filter 应用动画
*overflow 不为 hidden(在我们有需要时可以修改overflow = hidden来提升)
*不需要 paint 的 PaintLayer,比如说一个没有视觉属性(背景、颜色、阴影等)的空div
7、Graphics Layer
将Layer Tree上的某些节点进一步提升与合并
优势:
*通过GPU直接渲染,快于CPU(也即是通常所说的硬件加速)
*当需要repaint时,只需要 repaint 本身,不会影响其它层。
*对于 transform 和 opacity 效果,不会触发 layout 和 paint
生成 Graphics Layer:
*video、canvas元素、flash插件
*拥有perspective、CSS3D 变形的元素
*backface-visiblity 为 hidden
*对 opacity、 transform、 filter、 backdropfilter 应用了 animation 或者 transition
*设置了will-change属性的元素
*层之间的层叠遮盖