从 Chrome 看浏览器的渲染机制

Chrome 的多进程架构

进程 & 线程

在谈浏览器多进程架构之前,我们先聊聊进程和线程的概念。

进程是系统进行资源调度和分配的的基本单位,一个进程可以认为是一个程序的运行实例。启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程。

线程是依附于进程的,是操作系统可识别的最小执行和调度单位,而进程中使用多线程并行处理能提升运算效率,多线程可以并行处理任务,但是线程是不能单独存在的,它是由进程来启动和管理的。我们最熟悉的 JS 的运行就是线程这个维度。

下面是进程和线程间的一些区别:

  • 一个线程依附于一个进程,一个进程可以有多个线程;
  • 线程之间共享进程中的数据。
  • 进程中的任意一线程执行出错,都会导致整个进程的崩溃,而进程之前不会相互影响。
  • 当一个进程关闭之后,操作系统会回收进程所占用的内存。
  • 进程之间的内容相互隔离,只能通过 IPC 通信。

我觉得知乎上一个用火车比喻进程和线程的例子比较形象:进程好比火车,线程好比车厢,一辆火车有多节车厢,不同的火车之间互不干扰,但是一节车厢失火会殃及多节车厢。

Chrome 架构

从 Chrome 看浏览器的渲染机制_第1张图片

Chrome 浏览器包括:1 个 Browser 主进程、1 个 GPU 进程、1个 Utility 进程、多个 Renderer 进程和多个 Plugin 进程。

  • Browser 主进程(浏览器进程):主要负责界面显示、用户交互、子进程管理,同时还包含网络请求和文件访问等。
  • GPU 进程:与其他进程隔离处理 GPU 任务。
  • Renderer 进程(渲染进程):核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • Plugin 进程:主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

浏览器渲染机制

渲染进程的核心工作是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页。在这个工作过程中,输入的 HTML 经过一些子阶段,最后输出像素。按照渲染的时间顺序,这些子阶段大致可分为:构建 DOM 树、计算样式、布局、分层、绘制、分块、栅格化和合成。

从 Chrome 看浏览器的渲染机制_第2张图片

构建 DOM 树

当渲染进程开始接收 HTML 数据时,主线程开始解析 HTML 并将其转换为浏览器能够理解的 DOM 树结构。

从 Chrome 看浏览器的渲染机制_第3张图片

在 DOM 树的解析过程中,如果遇到 img、css 或者 js 资源时,主线程会向 Browser 主进程的网络线程发送请求以获取对应的资源。

当解析的过程中遇到