关键渲染路径
浏览器从最初接收请求来的HTML、CSS、javascript等资源经过一系列操作,最后呈现给用户能看到的界面这整个过程—关键渲染路径.
关键渲染路径包括:
- 构建对象模型(DOM,CSSOM)
- 构建渲染树(Render Tree):将 DOM 与 CSSOM 合并成一个渲染树
- 渲染布局,计算每个节点的位置
- 渲染绘制,调用 GPU 绘制,合成图层,显示在屏幕上

1. 构建对象模型(DOM,CSSOM)
无论是DOM还是CSSOM,都是要经过Bytes→characters→tokens→nodes→object model这个过程。

- 第一步(解析):从网络或者磁盘下读取的HTML原始字节码,通过设置的charset编码,转换成字符串
- 第二步(token化):通过词法分析器,将字符串解析成Token,Token中会标注出当前的Token是开始标签,还是结束标签,或者文本标签等。
- 第三步(生成Nodes并构建DOM树):浏览器会根据Tokens里记录的开始标签,结束标签,将Tokens之间相互串联起来(带有结束标签的Token不会生成Node)。
Node包含了这个节点的所有属性。事实上,在构建DOM树时,不是要等所有的Tokens都转换成Nodes后才开始,而是一边生成Token一边采取深度遍历算法消耗Token来生成Node,(如:首先生成出html Token,并消耗Token创建出html 节点对象,接着生成head Token并消耗Token创建出head节点对象……)当所有的Tokens都消耗完了,紧接着DOM树也就构建完了。
CSSOM的建立也经历上述过程,需要注意的是,由于因css样式存在后面的属性可能会覆盖掉前面的设置,浏览器规定CSSOM完全构建后才能使用.DOM和CSSOM构建是能同时进行的,不互斥,但中间遇到js脚本(不设置async/defer),就会发生阻塞
js脚本阻塞渲染
js阻塞还能分为两种情况:
- CSSOM构建完成时,DOM构建中,遇到js,会先下载js并执行,执行完后继续DOM构建
- CSSOM,DOM均未构建完成,遇到js,浏览器优先确保CSSOM构建,同时阻塞DOM构建(正常情况CSSOM/DOM是不互斥的)和JS执行,而且进一步的影响是CSSOM构建完成后,js还是继续阻塞着DOM构建,直到js执行完成
js阻塞实际上是阻塞的对象模型的构建.所以js位置很关键,css放头,js放尾
2. 构建渲染树(Render Tree)
我们已经拥有了完整的DOM树和CSSOM树。DOM 树上每一个节点对应着网页里每一个元素,CSSOM树上每个节点对应着网页里每个元素的样式,浏览器就可以通过它两构建渲染树了。浏览器会先从DOM树的根节点开始遍历每个可见节点,然后对每个可见节点找到适配的CSS样式规则并应用。
注意:
- Render 树上的每一个节点被称为:RenderObject。
- 渲染树和DOM树并不完全对应
- display: none的元素不在Render Tree中
- visibility: hidden的元素在Render Tree中
渲染树生成后,还是没有办法渲染到屏幕上,需要通过布局和渲染(绘制)才能最终呈现.
3.渲染树布局(layout of the render tree)
布局阶段会从渲染树的根节点开始遍历,由于渲染树的每个节点都是一个Render Object对象,包含宽高,位置,背景色等样式信息。所以浏览器就可以通过这些样式信息来确定每个节点对象在页面上的确切大小和位置,布局阶段的输出就是我们常说的盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。
需要注意的是:
- float元素,absoulte元素,fixed元素会发生位置偏移。
- 我们常说的脱离文档流,其实就是脱离Render Tree。
4.渲染树绘制(Painting the render tree)
在绘制阶段,浏览器会遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的。
浏览器主要组件

回流(重排)和重绘(reflow和repaint)
- reflow
当浏览器发现布局发生了变化,这个时候就需要倒回去重新渲染,这个回退的过程叫reflow。reflow会从html这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置,以确认是渲染树的一部分发生变化还是整个渲染树
- repaint
repaint则是当我们改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变。
参考:
浏览器渲染原理与流程
浏览器的渲染过程