渲染流程
渲染进程
渲染程序进程负责标签页内发生的一切。 合成器和光栅线程也会在渲染程序进程内运行,以便高效、流畅地渲染页面。 渲染程序进程的核心任务是将
HTML、CSS
和JavaScript
转换为用户可与之互动的网页。
渲染进程中的主线程会处理大多数工作,例如:
- 解析文本字符串 (
HTML
),生成DOM。
- 计算样式
- 布局
- 处理图层
- 每秒把⻚⾯画 60 次
- 执⾏全局 JS 代码
- 执⾏事件处理函数
- 执⾏计时器的回调函数
Web Worker
或 Service Worker
,则部分 JavaScript
将由工作器线程处理。
渲染流程
DOM
构建
为什么需要构建 DOM
树?
因为浏览器无法直接理解和使用 HTML,所以需要将
HTML
转换为浏览器能够理解的结构——DOM 树。
预加载资源
网站通常使用图片、CSS
和 JavaScript
等外部资源。
加快速度,系统会并发运行**“预加载扫描程序”**。如果 HTML
文档中包含 <img>
或 <link>
等内容,预加载扫描器会查看由 HTML
解析器生成的 token
,并将请求发送到浏览器进程中的网络线程。

js是如何阻止dom树构建
当HTML
解析器找到 <script>
标记时,它会暂停解析 HTML
文档,并加载、解析并执行 JavaScript
代码。因为 js
可能会修改当前已经生成的dom结构。
不管该脚本是否操纵了 CSSOM
,都会执行 CSS
文件下载,解析操作,再执行 JavaScript
脚本。JavaScript
会阻塞 DOM
生成,而样式文件又会阻塞 JavaScript
的执行。
样式计算(Recalculate Style)
样式计算的目的是为了计算出 DOM 节点中每个元素的具体样式,这个阶段大体可分为三步来完成:
- 把 CSS 转换为浏览器能够理解的结构——styleSheets。
- 转换样式表中的属性值,使其标准化(主要是将指标准化)。
- 计算出 DOM 树中每个节点的具体样式(遵守 CSS 的继承和层叠两个规则)
布局
布局是查找元素几何形状的过程。主线程会遍历 DOM 和计算出的样式,并创建包含 x y 坐标和边界框大小等信息的布局树。
布局树的结构可能与 DOM 树类似,但它仅包含与页面上可见内容相关的信息。 display: none
,则该元素不属于布局树的一部分(但是,具有 visibility: hidden
的元素位于布局树中)。
分层
渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)
那么需要满足什么条件,渲染引擎才会为特定的节点创建新的图层呢?
- 拥有层叠上下文属性的元素会被提升为单独的一层(position, z-index, filter: blur(5px), opacity
- 需要剪裁(clip)的地方也会被创建为图层
主线程会将该信息提交到合成器线程。
图层绘制
合成器线程会把一个图层的绘制拆分成很多图块,并将每个图块发送到光栅线程。
光栅化
光栅线程会光栅化每个图块并将其存储在 GPU 内存中。

合成和显示
将图块进行光栅化后,合成器线程会收集称为“绘制四边形”的图块信息,以创建合成器帧。然后通过 IPC 将合成器帧提交到浏览器进程。
合成的优势在于,它在完成时不涉及主线程。合成器线程不需要等待样式计算或 JavaScript 执行。因此,仅合成动画被认为是实现流畅性能的最佳方式。如果需要再次计算布局或绘制,则必须涉及主线程。
总结
- 渲染进程将
HTML
生成DOM
树结构 - 将
CSS
样式表 转换成styleSheets
- 创建布局树,并且计算布局信息(位置,是否显示)。
- 分层,生成图层树,提交给合成线程。
- 合成线程将图层分为多个图块,发给光栅线程。
- 光栅线程光栅化每个图块并存于
GPU
中 - 合成线程创建合成器帧 通过IPC提交给浏览器进程,界面更改,这些合成器帧会发送到
GPU
以在屏幕上显示。
...