深入了解现代网络浏览器(第 1 部分)

小作幸子

CPU、GPU、内存和多进程架构

在这个由 4 个部分组成的系列博文中,我们将深入探讨 Chrome 浏览器,从高级架构到渲染流水线的细节。如果你想知道浏览器如何将代码转换为可正常运行的网站,或者不确定为什么建议采用某种特定技术来提升性能,本系列视频就是为你准备的。

作为本系列文章的第 1 部分,我们将介绍核心计算术语以及 Chrome 的多进程架构。

计算机的核心是 CPU 和 GPU

如需了解浏览器的运行环境,我们需要了解计算机的一些部分及其功能。

CPU

CPU
图 1:办公室员工坐在每位办公桌前处理进来任务时的 4 个 CPU 核心

第一个是核心C进程 CC,即 C。CPU 可以视为计算机的大脑。CPU 核心(如图所示的办公室员工)可以在传入时逐一处理许多不同的任务。它可以处理数学、艺术等各种事务,还能知道如何回复客户来电。过去,大多数 CPU 都是单芯片。核心就像位于同一个芯片中的另一个 CPU。在现代硬件中,您通常会有多个核心,从而为手机和笔记本电脑提供更多计算能力。

GPU

GPU
图 2:许多 GPU 核心都带有扳手,建议其处理有限的任务

图形处理 Unit(即 GPU)是计算机的另一部分。与 CPU 不同,GPU 擅长处理简单的任务,但可以同时处理多个核心。顾名思义,它的开发初衷是为了处理图形。这就是为什么在图形上下文中“使用 GPU”或“基于 GPU 的”与快速渲染和流畅互动相关。近年来,随着 GPU 加速计算,越来越多的单靠 GPU 计算成为可能。

当您在计算机或手机上启动某个应用时,CPU 和 GPU 是应用的驱动因素。应用通常使用操作系统提供的机制在 CPU 和 GPU 上运行。

硬件、操作系统、应用
图 3:三层计算机架构。机器硬件位于底部,操作系统位于中间,应用位于顶部。

在 Process 和 Thread 上执行程序

进程和线程
图 4:作为边界框的流程,线程作为抽象的鱼在流程中游动

在深入了解浏览器架构之前,需要掌握的另一个概念是进程和线程。进程可以描述为应用的执行程序。线程是位于进程内并执行其进程程序任何部分的线程。

启动应用时,系统会创建一个进程。程序可能会创建线程来帮助其完成工作,但这不是必需的。操作系统会为进程提供内存“大块”,所有应用状态都保存在该私有内存空间中。当您关闭该应用时,进程也会消失,操作系统也会释放内存。

进程和内存
图 5:使用内存空间并存储应用数据的进程示意图

一个进程可以请求操作系统启动另一个进程来运行不同的任务。在这种情况下,系统会将内存的不同部分分配给新进程。如果两个进程需要通信,它们可以使用进程通信 (IPC) 实现。许多应用都以这种方式运作,这样一来,如果工作器进程无响应,则可以重启,而无需停止运行应用不同部分的其他进程。

工作器进程和 IPC
图 6:通过 IPC 进行通信的独立进程示意图

浏览器架构

那么,如何使用进程和线程构建网络浏览器?它既可以是具有许多不同线程的进程,也可以是由多个不同进程(多个线程通过 IPC 进行通信)的进程。

浏览器架构
图 7:不同的浏览器架构中的进程 / 线程图

需要注意的是,这些不同的架构属于实现细节。有关如何构建网络浏览器的标准规范。两个浏览器采用的方法可能完全不同

为了方便阅读本系列博文,我们将使用 Chrome 的最新架构,如图 8 所示。

顶部是浏览器进程协调处理应用不同部分的其他进程。对于渲染程序进程,系统会创建多个进程并将其分配给每个标签页。不久之前,Chrome 会尽可能为每个标签页都提供一个进程;现在,它会尝试为每个网站提供专属进程,包括 iframe(请参阅网站隔离)。

浏览器架构
图 8:Chrome 的多进程架构示意图。“Renderer Process”下会显示多个图层,以表示 Chrome 会针对每个标签页运行多个渲染程序进程。

哪个进程控制着什么?

下表介绍了每个 Chrome 进程及其控制的进程:

流程及控制对象
Browser 控制应用的“Chrome”部分,包括地址栏、书签、后退按钮和前进按钮。
此外,还处理网络浏览器中不可见的特权部分,例如网络请求和文件访问。
渲染程序 控制标签页中显示网站的一切内容。
插件 控制网站使用的所有插件,例如 Flash。
GPU 独立于其他进程处理 GPU 任务。它分为不同的进程,因为 GPU 会处理来自多个应用的请求并在同一 Surface 中绘制它们。
Chrome 进程
图 9:指向浏览器界面不同部分的不同进程

还有更多进程,比如扩展进程和实用程序进程。如果您想查看 Chrome 中正在运行的进程,请点击右上角的选项菜单图标 ,选择“更多工具”,然后选择“任务管理器”。此时将打开一个窗口,其中包含当前正在运行的进程及其占用的 CPU/内存量。

Chrome 中多进程架构的优势

之前我提到过 Chrome 使用多个渲染程序进程。在最简单的情况下,您可以假设每个标签页都有自己的渲染程序进程。假设您打开了 3 个标签页,每个标签页都由独立的渲染程序进程运行。

如果某个标签页无响应,您可以关闭无响应标签页并继续,同时让其他标签页保持活跃状态。如果所有标签页都在一个进程上运行,那么当一个标签页无响应时,所有标签页都无响应。真遗憾。

多个标签页的渲染程序
图 10:该图显示了运行每个标签页的多个进程

将浏览器工作分为多个进程的另一个好处是安全性和沙盒。由于操作系统提供了一种限制进程权限的方法,因此浏览器可以沙盒化某些功能,让特定进程发挥特定功能。例如,Chrome 浏览器会限制处理任意用户输入的进程(例如渲染程序进程)对任意文件的访问权限。

由于进程有自己的专用内存空间,因此进程通常包含通用基础架构的副本(例如,V8,这是 Chrome 的 JavaScript 引擎)。这意味着内存使用量更高,因为它们不能像它们是同一进程中的线程时那样共享。为了节省内存,Chrome 对可以启动的进程数量设置了限制。 该上限因设备的内存和 CPU 性能而异,但当 Chrome 达到上限时,便会开始在一个进程中运行来自同一网站的多个标签页。

节省更多内存 - Chrome 中的服务

该方法也适用于浏览器进程。Chrome 正在进行架构更改,以便将浏览器程序的每个部分作为一项服务来运行,从而允许拆分为不同的进程或聚合为一个进程。

一般来说,当 Chrome 在强大的硬件上运行时,可能会将每项服务拆分为不同的进程,以提高稳定性;但如果是在资源有限的设备上,Chrome 会将各项服务合并为一个进程,从而节省内存占用量。在此变更之前,类似的方法整合进程以减少内存用量,就已经在 Android 等平台上使用。

Chrome 服务化
图 11:Chrome 服务将不同服务移入多个进程和一个浏览器进程的示意图

每帧渲染程序进程 - 网站隔离

网站隔离是 Chrome 中最近推出的一项功能,可为每个跨网站 iframe 运行单独的渲染程序进程。我们一直在讨论每个标签页模型一个渲染程序进程,它允许跨网站 iframe 在单个渲染程序进程中运行,并在不同网站之间共享内存空间。可以在同一渲染程序进程中运行 a.com 和 b.com。同源政策是网络的核心安全模型;它可以确保一个网站在未经同意的情况下无法访问来自其他网站的数据。绕过此政策是安全攻击的主要目标。 进程隔离是隔离网站的最有效方法。在 Meltdown 和 Spectre 中,我们需要使用进程来分隔网站,这一点变得更加明显。从 Chrome 67 开始,系统会在桌面设备上默认启用网站隔离功能,因此标签页中的每个跨网站 iframe 都会获得单独的渲染程序进程。

网站隔离
图 12:网站隔离示意图;多个渲染程序进程都指向网站内的 iframe

启用网站隔离功能是一项需要多年的工程工作。网站隔离不像分配不同的渲染程序进程那样简单,它会从根本上改变 iframe 之间的通信方式。在 iframe 在不同进程上运行的页面上打开开发者工具,意味着开发者工具必须实现后台工作,才能流畅显示。即使运行简单的 Ctrl+F 键查找网页中的某个字词,也要在不同的渲染程序进程中进行搜索。这就是为什么浏览器工程师谈到网站隔离功能的发布是一个主要里程碑的原因!

小结

在这篇博文中,我们对浏览器架构进行了简要的介绍,并介绍了多进程架构的优势。我们还介绍了 Chrome 中的服务化和网站隔离,这与多进程架构密切相关。在下一篇帖子中,我们将开始深入讨论这些进程和线程之间发生的情况,以便显示网站。

您喜欢这个帖子吗?如果您对日后发布的博文有任何疑问或建议,请随时通过 @kosamari 在 Twitter 上告诉我们。

下一步:导航中会出现什么情况