页面渲染的原理及流程
浏览器将域名通过网络通信从服务器拿到html文件后,如何渲染页面呢?
- 根据html文件构建DOM树和CSSOM树。构建DOM树期间,如果遇到JS,阻塞DOM树及CSSOM树的构建,优先加载JS文件,加载完毕,再继续构建DOM树及CSSOM树。
- 构建渲染树。
- 页面的重绘与重排(也有称回流)。页面渲染完成后,若JS操作了DOM节点,根据JS对DOM操作动作的大小,浏览器对页面进行重绘或者是重排。
一、构建DOM树及CSSOM树
1.1构建DOM树
-
DOM节点树中节点与HTML文档中内容一一对应,DOM树构建过程:读取HTML文档,将字节转换成字符,确定tokens(标签),再将tokens转换成节点,以节点构建DOM树。
-
HTML文档中的所有内容皆是节点,各节点之间拥有层级关系,如父子关系等、兄弟关系等,彼此相连,构成DOM树。最常见的几种节点有:文档节点、元素节点、文本节点、属性节点、注释节点。
-
1.2构建CSSOM树
-
CSS文档中,所有元素皆是节点,与HTML文件中的标签节点一一对应。CSSS中各节点之间同样拥有层级关系,如父子关系等、兄弟关系等,彼此相连,构成CSSOM树。在构建DOM树的过程中,与HTML文档head标签中遇到link标签,该标签引用了一个外部CSS样式表。由于预见需要利用该CSS资源来渲染页面,浏览器会立即发出对该CSS资源的请求,并进行CSSOM树的构建。
-
CSSOM树构建过程与DOM树构建流程一致:读取HTML文档,将字节转换成字符,确定tokens(标签),再将tokens转换成节点,以节点构建CSSOM树。
-
.CSS文件,又名层叠样式表。当CSSOM树生成节点时,每一个节点首先会继承其父节点的所有样式,层叠覆盖,然后再以“向下级联”的规则,为该节点应用更具体的样式,递归生成CSSOM树。
二、构建渲染树
- 渲染树由DOM树、CSSOM树合并而成,但并不是必须等DOM树及CSSOM树加载完成后才开始合并构建渲染树。三者的构建并无先后条件,亦非完全独立,而是会有交叉、并行构建。因此会一边加载,一边解析,一边渲染的工作现象。
- 构建渲染树,根据渲染树计算每个可见元素的布局,并输出到绘制流程,将像素渲染到屏幕上。
三、页面的重绘(repaint)与重排(reflow)
3.1重绘:屏幕的一部分要重绘。渲染树节点发生改变,但不影响该节点在页面当中的空间位置及大小。譬如某个div标签节点的背景颜色、字体颜色等等发生改变,但是该div标签节点的宽、高、内外边距并不发生变化,此时触发浏览器重绘。
3.2重排: 也有称回流,当渲染树节点发生改变,影响了节点的几何属性,导致节点位置发生变化,此时触发浏览器重排,需要重新生成渲染树,重新布局,即重排。
**注意:重排必将引起重绘,而重绘不一定会引起重排。
何时会引起重排?
当页面布局和几何属性改变时就需要从排。下述情况会发生浏览器重排:
- 添加或者删除可见的DOM元素;
- 元素位置改变——display、float、position、overflow等;
- 元素尺寸改变——边距、填充、宽度、高度;
- 内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;
- 页面渲染初始化;
- 浏览器窗口尺寸改变——resize事件发生时;
3.3如何减少和避免重排
重排的成本比重绘高的多的多。一个节点的重排很有可能导致子节点,甚至父节点以及兄弟节点的重排。在一些高性能的电脑上也许没什么,但重排发生在手机上,那么这个过程是延慢加载和耗电的
- 直接改变className,如果动态改变样式,则使用cssText(考虑没有优化的浏览器);
- 让要操作的元素进行“离线处理”,处理完后一起更新;a、使用DocumentFragment进行缓存操作,引发一次回流和重绘;
b、使用display:none技术,只引发两次回流和重绘;
c、使用cloneNode(true or false) 和 replaceChild 技术,引发一次回流和重绘; - 不要经常访问会引起浏览器flush队列的属性,如果你确定要访问,利用缓存;
- 让元素脱离动画流,减少回流的Render Tree的规模;