谈谈对浏览器渲染及优化渲染性能的理解
这里主要谈的是Gecko和Webkit这两种渲染引擎,FireFox基于Gecko构建,Safari和Chrome基于Webkit构建。
浏览器渲染流程主要分为以下几步:
- 解析HTML,构建DOM树
浏览器在加载网站时,会从服务器上下载HTML文件,浏览器把这个文件解析成为DOM树。在构建这个树的时候是采用深度遍历构建,当前节点的所有子节点遍历完后才会去遍历兄弟节点。 - 获取并解析CSS文件,构建CSSOM树
浏览器在遇到指向CSS文件的链接时,会获取CSS文件,并对其解析。在拿到这个CSS文件后,会像构建DOM树一样,构建树形的CSSOM树。其中包含了网页的样式的层次结构。 - 生成渲染树(Render-Tree)
这里要构建另外一个树结构—Render Tree。在渲染树中,每个节点都是表示要渲染在屏幕上的信息。虽然感觉和DOM树差不多,但是两者之间并不是一对一的关系,因为有些隐藏的元素不会在渲染树中,如display:none的节点,而伪元素会在这里渲染出对象,但是在DOM树中却没有。还有就是布局脱离了正常文档流的节点也和DOM的位置不一样,RenderTree是根据实际位置渲染的。 - 布局/重排
这个过程是计算每个渲染对象的几何属性,确定每个对象在页面的具体位置。浏览器会从根节点开始依次递归往下。 - 绘制
绘制即遍历Render树,通过浏览器的UI后端层去绘制每个节点。
对于Gecko和Webkit两个主流渲染引擎渲染网站的流程基本相同,都是
构建DOM树 -> 构建CSSOM树 -> 生成Render树 -> 布局/重排 ->绘制
Webkit引擎渲染流程:
Gecko引擎渲染流程:
可以看出两个引擎基本流程一样,只是在Gecko中多了个Content Sink,是用来创建DOM树的工厂。布局在Gecko被称为重排(Reflow),而在Webkit里面称为布局(layout),其实是一个意思。Gecko将Render树称为Frame Tree(帧树)。
优化渲染性能
当页面有了变化,那么页面就要重新渲染。
根据变化的不同,重新渲染的步骤也不一样,如只滚动了页面,那么浏览器只需要重新绘制,呈现到屏幕就行;如果样式改变了元素的位置或宽高,那么浏览器就需要重排,然后重绘这次改动受影响的部分;如果只变化了文字颜色,浏览器就不需要重排只需要后续的重绘即可。
重排一定有重绘,重绘不一定有重排
如何优化渲染呢?
重绘相对于重排而言,几乎不会影响性能。我们只需要将重排次数、重排范围尽可能减少,就可以提高渲染性能。
- 在布局上来说,多使用局部布局,避免对全局的范围的重排。使用局部布局,重排只需要对这个局部重排,而不会影响全局,也会提高渲染重排速度,提高渲染效率。
- 修改DOM样式,一次性就改完,不要一次一次地修改,或者事先定义好类样式,修改DOM的className。这样做可以减少重排。
暂时先写这么多,以后再补充
如有错误之处,敬请斧正