浏览器渲染原理
约 769 字大约 3 分钟
2025-03-14
提问
- 请说说浏览器渲染页面的过程
浏览器在拿到 HTML 文档后,会产生一个渲染任务,并将其传递给渲染主线程的消息队列。在事件循环机制的作用下,渲染主线程取出渲染任务开始渲染流程。
渲染流程
整个渲染流程分为多个阶段: HTML解析、样式计算、布局、分层、绘制、分块、光栅化、展示。
每个阶段都有明确的输入和输出,形成一套严密的生产流水线。
解析HTML
输入:HTML文档
输出:DOM树、CSSOM树
解析HTML过程中遇到CSS会解析CSS,遇到JS会执行JS。为了提高效率,浏览器在开始解析前会启动预解析线程,先行下载HTML中用到的外部的CSS、JS文件。
下载和解析CSS文件的工作是在预解析线程中进行的,所以CSS解析不会阻塞主线程。
而JS执行可能会影响DOM树,因此执行JS时主线程会被阻塞。
本阶段完成后,会得到DOM树和CSSOM树,浏览器默认样式、内部样式、行内样式均会包含在CSSOM树中。
样式计算
输入:DOM树、CSSOM树
输出:带样式的DOM树
主线程会一次遍历DOM树,为树中每个节点计算出最终样式(Computed Style)。
这一过程中,很多预设值会转变成绝对值,相对单位会转变成绝对单位。
这一阶段完成后,会得到一棵带样式的DOM树。
布局
输入:带样式的DOM树
输出:布局树
依次遍历DOM树的每一节点,计算节点几何信息(宽高、相对包含快的位置)。
提示
大部分时候,布局树和DOM树并非一一对对应。
比如 display: none
的节点没有几何信息,因此不会生成到布局树;又如伪元素选择器,虽然DOM书中不存在这些伪元素节点,但是他们拥有几何信息, 因此会被天机道布局树中。
本阶段完成后会产生一棵布局树。
分层
主线程会根据库一套复杂的策略对整个布局树进行分层。
分层的优势在于:将来某一层改变后,仅会对该层进行处理,提升效率。
可能影响分层的事物:
- 滚动条
- 堆叠上下文
- transform
- opacity
- will-change属性
绘制
对每一层生成绘制指令集,描述如何绘制该层内容。
分块
完成分层后,主线程将信息提交给合成线程,剩余工作在合成线程中完成。
合成线程先将每个图层分块,划分成更多的小区域。
光栅化
将每个快变成位图,优先处理靠近视口的分块。
展示
最后调用GPU硬件将页面渲染到屏幕上。