前端(五):浏览器渲染流程

93 阅读4分钟

详细的浏览器渲染流程

1. 浏览器接收 HTML 文档

当用户在浏览器中输入 URL 并按下回车键时,浏览器会向服务器发送 HTTP 请求以获取 HTML 文档。一旦收到响应,浏览器便开始渲染流程。

2. 构建 DOM 树(DOM Construction)

起始阶段:浏览器从 HTML 文档的第一个字节开始,逐步解析 HTML 内容,构建 DOM 树。DOM 树是页面结构的内存表示,包含了所有的 HTML 元素及其属性。

预解析(Pre-parsing)与预加载(Pre-loading):在构建 DOM 树的同时,浏览器会进行预解析。这意味着浏览器会扫描文档,查找需要加载的资源(如 CSS、JavaScript 文件、图片等)的 URL,并尽可能并行地发送请求以预加载这些资源。预解析不会阻塞 DOM 树的构建,但会影响资源的加载顺序。

注意:虽然预解析与 DOM 树的构建是并行进行的,但从流程上讲,是先开始构建 DOM 树,同时进行预解析。

3. 构建 CSSOM 树(CSSOM Construction)

随着 CSS 文件(通过 <link> 标签引入)的下载和解析,浏览器会构建 CSSOM 树。CSSOM 树包含了所有的样式声明及其层次关系。CSSOM 树的构建依赖于 CSS 文件的加载,但它不会阻塞 DOM 树的构建。然而,渲染树(Render Tree)的生成需要等待 DOM 树和 CSSOM 树都构建完成。

注意:HTML 文档中元素标签的内联样式和 <style> 标签中的样式,也会参与到 CSSOM 树的构建。

4. 渲染树(Render Tree)的生成

一旦 DOM 树和 CSSOM 树都构建完成,浏览器会将它们合并成一个渲染树。渲染树包含了所有需要显示的节点以及它们的样式信息。这个阶段是确定页面最终布局的关键步骤。

5. 布局(Layout)

浏览器根据渲染树进行布局计算,确定每个节点在屏幕上的确切位置和大小。这个过程可能会多次发生,特别是在页面上的元素大小或位置发生变化时。

6. 绘制(Paint)

在布局完成后,浏览器将渲染树的节点绘制到屏幕上。绘制过程通常包括多个图层(Layers)的绘制和合成,以提高渲染效率。

7. 重排和重绘(Reflow & Repaint)

页面上的任何变动(如 JavaScript 修改 DOM 或 CSSOM)都可能触发重排或重绘。

重排需要重新计算元素的布局;重绘仅影响元素的样式,不改变布局。

重排一定会导致重绘,重绘不一定会引起重排。

加载顺序与阻塞

  • CSS 文件:CSS 文件的加载不会阻塞 DOM 的解析,但会阻塞渲染树的生成,直到 CSSOM 树构建完成。

  • JavaScript 文件

    • 同步脚本:会阻塞 DOM 的解析,因为浏览器在解析 HTML 文档时,遇到 <script> 标签且该标签没有 asyncdefer 属性时,会立即停止解析 HTML 文档,转而下载并执行脚本,直到脚本下载且执行完毕后才能继续解析后续的HTML 内容,这个过程会一直阻塞 DOM 的解析。

    • 异步脚本(async)不会阻塞 DOM 的解析,但可能会阻塞渲染树的生成。脚本会异步下载,也就是说下载脚本和 DOM 解析是同时进行的。但是一旦脚本下载完成,DOM 解析就会暂停,转而执行脚本,待脚本执行完毕,再继续进行 DOM 解析。注意这里是"暂停",而不是"阻塞"。如果 DOM 解析中途暂停时间较长,在感觉上就好像是渲染树被阻塞了。

    • 延迟脚本(defer)既不会阻塞 DOM 的解析,也不会阻塞渲染树的生成。脚本也会异步下载,不同的是无论下载何时完成,脚本都会等待整个 DOM 解析完成后才执行。这意味着 DOM 和 CSSOM 都已经构建完成,也就不会阻塞渲染树了。但是,如果脚本修改了 DOM 或 CSSOM,那么渲染树会根据这些修改进行更新。

  • 图片和其他资源:这些资源的加载通常是异步的,不会阻塞 DOM 的解析,但可能会影响页面的绘制速度。