原文:Inside look at modern web browser (part 1)
CPU, GPU, Memory, 和 多进程架构(multi-process architecture)
在该系列文章中,我们将从浏览器架构到渲染管道的细节来了解现代浏览器。如果你对浏览器是如何将代码转化为一个功能性的网站感到好奇,或者对一项技术被建议用于性能提升感到疑问,那么,该系列文章是为你而准备的
在第一篇文章中,我们将会了解核心计算术语以及Chrome浏览器的多进程架构(multi-process architecture)
计算机的核心是CPU和GPU
为了理解浏览器的运行环境,我们需要了解一些计算机的组成部分以及它们做了什么。
CPU
首先是CPU(Central Processing Unit)。CPU可以理解为计算机的大脑。一个CPU core,就像是下图中的一个员工,它们能够一个接一个的处理接收到的任务。它能够处理从数学到艺术的所有事情,同时知道如何回复顾客电话。在以前,大部分CPU是单核的,现在的CPU大多是多核,因此,它能够提供更强大的计算能力
GPU
GPU —— Graphics Processing Unit(图形处理单元)是计算机的另一组成部分。和CPU不同,GPU擅长处理简单的任务,但同时跨域多个core(PS:因为CPU是多核的,GPU能够在这多核中同时处理多个任务)。顾名思义,GPU被开发出来是用于处理图像的。这也是为什么在图形环境中将”using GPU“ 或 ”GPU-backed"与快速渲染和交互流畅关联起来。在最近几年中,随着GPU的加速计算,越来越多的计算在GPU上变成可能
问题: 「和CPU不同,GPU擅长处理简单的任务,但同时跨域多个core」—— GPU是如何在多核中进行处理的?是不是GPU也有很多core,然后为不同的CPU core分配不同数量的GPU core?
当在电脑或手机上启动一个app,CPU和GPU就开始为该app服务。通常,app利用操作系统提供的机制在CPU和GPU上运行
在进程(Process)和线程(Thread)上执行程序
在深入了解浏览器架构之前还需要知道Process和Thread(进程和线程)的原理。进程可以描述为一个应用程序的执行程序,线程存在于进程中,用于执行所在进程的部分程序。
当启动一个应用时,会相应的创建进程。该应用有可能也会创建线程用来辅助它工作,但这是可选的。操作系统为进程分配内存空间用于存储应用程序的数据。当关闭应用时,进程被销毁,同时操作系统会释放其占用的内存控件。
一个进程可以请求操作系统启动另一个进程来执行不同的任务。操作系统会为新进程分配内存,如果两个进行需要通信,可以使用IPC(Inter Process Communication)来完成。许多应用程序以这种方式设计是为了当一个进程没有响应时,它只需要重启自己,而不必终止该应用中执行其他功能的进程。
浏览器架构(Browser Architecture)
那么,如何使用进程和线程来构建浏览器?可以是一个进程包含许多个不同的线程,或者是许多不同的进程通过几个线程使用IPC来通信。
需要注意的一点是不同的架构实现细节是不同的,并没有一个标准规范来规定要如何去构建一个浏览器,一个浏览器的实现可能完全不同于另一个浏览器。
在本系列博文中,我们将使用下图中描述的最新Chrome架构。
上层是浏览器进程,它协调那些处理应用程序不同组成部分的进程。对于渲染进程,会创建多个进程并将其分配到每个tab上。直到最近,Chrome还在可能的情况下为每个tab提供一个进程;现在,Chrome尝试为每个站点提供自己的,包括iframe(Site Isolation)
每个进程控制什么?
下表展示了Chrome中每个进程以及它们的工作
| 进程 | 工作 |
|---|---|
| Browser Process | 控制浏览器的部分应用包括地址栏、书签、后退和前进按钮。也处理隐私模式、浏览器的部分权限,例如网路请求和文件权限 |
| Render Process | 控制tab中网站内容的展示 |
| Plugin Process | 控制网站中被使用的插件,例如:flash |
| GPU Process | 独立于其他进程处理GPU任务。它被拆分到不同的进程中,因为GPUs需要处理来自多个应用的请求,并将其绘制在同一个页面上 |
还有更多的进程,例如Extension Process和Utility Process。如果想要查看Chrome运行了多少进程,可以点击顶部右侧菜单栏的三个小点,选择更多工具,然后点击Task Manager,会打开一个新的窗口,在里面列出了当前运行的进程列表,以及它们占用了多少CPU/内存。
Chrome中多进程架构带来的好处
在前面提到了Chrome使用了多个渲染进程。在大多数简单的场景中,可以想象每个进程有它自己的渲染进程。假如打开了3个tab页,每个tab页由一个独立的渲染进程运行,如果其中一个tab页没有响应了,我们关闭该tab页,其他tab页还是可以继续运行,而不会受到影响。假如所有的tab页都在同一个渲染进程中运行,当其中一个tab页没有响应,那么所有的tab页都会受到影响,没有响应。
使浏览器工作在多进程架构下的另一个好处是更加安全和沙箱机制。由于操作系统提供了限制进程权限的一种方法,浏览器可以从某些功能中对某些进程进行沙箱处理。例如,Chrome浏览器限制一些进程随意的文件访问,如渲染进程。
因为进程有他们自己私有的内存空间,所以他们含有公共基础设施的副本(就像Chrome的JavaScript V8引擎)。这意味着更多的内存使用,因为如果它们是同一个进程中的线程,它们就无法共享。为了节省内存,Chrome限制了它可以启用的进程数量。该数量取决于内存容量以及CPU的性能,但是当Chrome达到该该数量后,将会在同一个进程中运行同一个站点的多个tab页(简单的说就是将相同站点的多tab页面放在一个渲染进程中运行)
节省更多的内存 —— Chrome中的服务化
同样的方法被用于浏览器进程。Chrome正在经历架构上的调整,以便将浏览器中的每一部分当做一个服务去运行,从而可以轻松地拆分到不同的进程或者集成为一个。
总体思路是,当浏览器运行在性能强劲的硬件设备上时,它会将每个服务器拆分到不同的进程,以获取跟高的稳定性;但是,如果运行在资源比较匮乏的设置上是,会将多个服务整合到一个进程中,以节省内存占用。在此改变之前,已在Android等平台上使用类似的方法来减少内存占用.
Per-frame Render Process —— 站点隔离(Site Isolation)
Site Isolation 是最近在Chrome中才被介绍的特性。它为每一个跨站点iframe运行一个独立的渲染进程。我们一直在讨论一个tab模型一个渲染进程,它允许跨站点iframe运行在一个单独的渲染进程,并在不同的站点共享内存空间。在同一个渲染进程中运行a.com和b.com看起来是ok的。Same Origin Policy(同源策略)是web中一个核心的安全策略,它禁止站点未经许可的情况下访问其他站点的数据,安全攻击的主要目标就是绕开安全限制。进程隔离是站点分离最有效的方式,由于Meltdown and Spectre的存在,使用进程进行站点隔离变得更加必要了。从Chrome 67版本开始,站点隔离在Chrome桌面端已被默认开启,在一个tab中,每个跨站iframe都将获得一个独立的渲染进程。
经过多年的努力才启用站点隔离。站点隔离并不像分配不同的渲染进程这么简单,它基本上改变了iframe彼此之间通信的方式。在iframe运行于不同进程的页面上打开devtools,意味着devtool需要在背后做很多额外的工作,以便使的这个过程看起来是无缝连接的。甚至在页面上执行简单的Ctrl + F操作来搜索文字,也意味着需要跨越不同的进程进行搜索。这也是为什么工程师会将站点隔离的发布当做一个里程碑的原因
Wrap-up
在这篇文章中,涵盖了浏览器架构的高层视角和多进程架构的好处,也谈及了Chrome中的服务化和站点隔离是与多进程架构有很深的联系,在下篇文章中,将继续深挖为了显示一个页面,在进程和线程之间发生了什么