窥探现代浏览器架构(一)

前言

本文是笔者对Mario Kosaka写的inside look at modern web browser系列文章的翻译。这里的翻译不是指直译,而是结合我的的理解将做者想表达的意思表达出来,并且会尽可能补充一些相关的内容来帮助你们更好地理解。git

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

在这个4集系列教程里面,我将会从Chrome浏览器的高层次架构(high-level architecture)开始提及,一直深刻讲到页面渲染流水线(rendering pipeline)的具体细节。若是你想知道浏览器是怎么把你编写的代码转变成一个可用的网站,或者你不知道为何一些特定的代码写法能够提升网站的性能的,那你就来对地方了,这篇文章就是为你准备的。github

做为本系列文章的第一篇,咱们会先了解一些关键的计算机术语以及Chrome浏览器的多进程架构web

计算机的核心 - CPU和GPU

要想理解浏览器的运行环境,咱们先要搞明白一些计算机组件以及它们的做用。浏览器

CPU

首先咱们要说的是计算机的大脑 - CPU(Central Processing Unit)。CPU是计算机里面的一块芯片,上面有一个或者多个核心(core)。咱们能够把CPU的一个核心(core)比喻成一个办公室工人,他功能强大,上知天文下知地理,琴棋书画无所不能,它能够串行地一件接着一件处理交给它的任务。好久以前的时候大多数CPU只有一个核心,不过在如今的硬件设备上CPU一般会有多个核心,由于多核心CPU能够大大提升手机和电脑的运算能力。

<p align="center">四个CPU核心愉快地在各自工位上一个接着一个地处理交给它们的任务</p>安全

GPU

图形处理器 - 或者说GPU(Graphics Processing Unit)是计算机的另一个重要组成部分。和功能强大的CPU核心不同的是,单个GPU核心只能处理一些简单的任务,不过它胜在数量多,单片GPU上会有不少不少的核心能够同时工做,也就是说它的并行计算能力是很是强的。图形处理器(GPU)顾名思义一开始就是专门用来处理图形的,因此在说到图形使用GPU(using)或者GPU支持(backed)时,人们就会联想到图形快速渲染或者流畅的用户体验相关的概念。最近几年来,随着GPU加速概念的流行,在GPU上单独进行的计算也变得愈来愈多了。

<p align="center">每一个GPU核心手里只有一个扳手,这就说明它的能力是很是有限的,但是它们人多啊!</p>网络

当你在手机或者电脑上打开某个应用程序的时候,背后实际上是CPU和GPU支撑着这个应用程序的运行。一般来讲,你的应用要经过操做系统提供的一些机制才能跑在CPU和GPU上面。

<p align="center">计算机的三层架构,最下层是硬件机器,操做系统夹在中间,最上层是运行的应用</p>架构

在进程和线程上执行程序

在深刻到浏览器的架构以前咱们还得了解一下进程(process)和线程(thread)的相关概念。进程能够当作正在被执行的应用程序(executing program)。而线程是跑在进程里面的,一个进程里面可能有一个或者多个线程,这些线程能够执行任何一部分应用程序的代码。

<p align="center">进程就像一个大鱼缸,而线程就是浴缸里面畅游的鱼儿</p>ide

当你启动一个应用程序的时候,操做系统会为这个程序建立一个进程同时还为这个进程分配一片私有的内存空间,这片空间会被用来存储全部程序相关的数据和状态。当你关闭这个程序的时候,这个程序对应的进程也会随之消失,进程对应的内存空间也会被操做系统释放掉。

<p align="center">进程使用系统分配的内存空间去存储应用的数据</p>工具

有时候为了知足功能的须要,建立的进程会叫系统建立另一些进程去处理其它任务,不过新建的进程会拥有全新的独立的内存空间而不是和原来的进程共用内存空间。若是这些进程须要通讯,它们要经过IPC机制(Inter Process Communication)来进行。不少应用程序都会采起这种多进程的方式来工做,由于进程和进程之间是互相独立的它们互不影响,换句话来讲,若是其中一个工做进程(worker process)挂掉了其余进程不会受到影响,并且挂掉的进程还能够重启。

<p align="center">不一样的进程经过IPC来通讯</p>性能

浏览器架构

那么浏览器是怎么使用进程和线程来工做的呢?其实大概能够分为两种架构,一种是单进程架构,也就是只启动一个进程,这个进程里面有多个线程工做。第二种是多进程架构,浏览器会启动多个进程,每一个进程里面有多个线程,不一样进程经过IPC进行通讯。

<p align="center">单进程和多进程浏览器的架构图</p>

上面的图表架构其实包含了浏览器架构的具体实现了,在现实中其实并无一个你们都遵循的浏览器实现标准,因此不一样浏览器的实现方式可能会彻底不同。

为了更好地在本系列文章中展开论述,咱们主要讨论最新的Chrome浏览器架构,它采用的是多进程架构,如下是架构图:

<p align="center">Chrome的多进程架构图,多个渲染进程的卡片(render process)是用来代表Chrome会为每个tab建立一个渲染进程。</p>

Chrome浏览器会有一个浏览器进程(browser process),这个进程会和其余进程一块儿协做来实现浏览器的功能。对于渲染进程(renderer process),Chrome会尽量为每个tab甚至是页面里面的每个iframe都分配一个单独的进程。

各个进程如何分工合做呢?

如下是各个进程具体负责的工做内容:

进程 负责的工做
Browser 负责浏览器的“Chrome”部分, 包括导航栏,书签, 前进和后退按钮。同时这个进程还会控制那些咱们看不见的部分,包括网络请求的发送以及文件的读写。
Renderer 负责tab内和网页展现相关的全部工做。
Plugin 控制网页使用的全部插件,例如flash插件。
GPU 负责独立于其它进程的GPU任务。它之因此被独立为一个进程是由于它要处理来自于不一样tab的渲染请求并把它在同一个界面上画出来。


<p align="center">不一样的进程负责浏览器不一样部分的界面内容</p>

除了上面列出来的进程,Chrome还有不少其余进程在工做,例如扩展进程(Extension Process)和工具进程(utility process)。若是你想看一下你的Chrome浏览器如今有多少个进程在跑能够点击浏览器右上角的更多按钮,选择更多工具和任务管理器:

在弹出的窗口里面你会看到正在工做的进程列表,以及每一个进程使用的CPU和内存情况。

Chrome多进程架构的好处

那么为何Chrome会采起多进程架构工做呢?

其中一个好处是多进程可使浏览器具备很好的容错性。对于大多数简单的情景来讲,Chrome会为每一个tab单独分配一个属于它们的渲染进程(render process)。举个例子,假如你有三个tab,你就会有三个独立的渲染进程。当其中一个tab的崩溃时,你能够随时关闭这个tab而且其余tab不受到影响。但是若是全部的tab都跑在同一个进程的话,它们就会有连带关系,一个挂所有挂。

<p align="center">不一样的tab会有不一样的渲染进程来负责</p>

Chrome采用多进程架构的另一个好处就是能够提供安全性和沙盒性(sanboxing)。由于操做系统能够提供方法让你限制每一个进程拥有的能力,因此浏览器可让某些进程不具有某些特定的功能。例如,因为tab渲染进程可能会处理来自用户的随机输入,因此Chrome限制了它们对系统文件随机读写的能力。

不过多进程架构也有它很差的地方,那就是进程的内存消耗。因为每一个进程都有各自独立的内存空间,因此它们不能像存在于同一个进程的线程那样共用内存空间,这就形成了一些基础的架构(例如V8 JavaScript引擎)会在不一样进程的内存空间同时存在的问题,这些重复的内容会消耗更多的内存。因此为了节省内存,Chrome会限制被启动的进程数目,当进程数达到必定的界限后,Chrome会将访问同一个网站的tab都放在一个进程里面跑

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

一样的优化方法也能够被使用在浏览器进程(browser process)上面。Chrome浏览器的架构正在发生一些改变,目的是将和浏览器自己(Chrome)相关的部分拆分为一个个不一样的服务,服务化以后,这些功能既能够放在不一样的进程里面运行也能够合并为一个单独的进程运行。

这样作的主要缘由是让Chrome在不一样性能的硬件上有不一样的表现。当Chrome运行在一些性能比较好的硬件时,浏览器进程相关的服务会被放在不一样的进程运行以提升系统的稳定性。相反若是硬件性能很差,这些服务就会被放在同一个进程里面执行来减小内存的占用。其实在此次架构变化以前,Chrome在Android上面已经开始采起相似的作法了。

<p align="center">Chrome将浏览器相关的服务放在同一个进程里面运行和放在不一样的进程运行的区别</p>

单帧渲染进程 - 网站隔离(Site Isolation)

网站隔离(Site Isolation)是最近Chrome浏览器启动的功能,这个功能会为网站内不一样站点的iframe分配一个独立的渲染进程。以前说过Chrome会为每一个tab分配一个单独的渲染进程,但是若是一个tab只有一个进程的话不一样站点的iframe都会跑在这个进程里面,这也意味着它们会共享内存,这就有可能会破坏同源策略。同源策略是浏览器最核心的安全模型,它能够禁止网站在未经赞成的状况下去获取另一个站点的数据,所以绕过同源策略是不少安全攻击的主要目的。而进程隔离(proces isolation)是隔离网站最好最有效的办法了。再加上CPU存在Meltdown和Spectre的隐患,网站隔离变得势在必行。所以在Chrome 67版本以后,桌面版的Chrome会默认开启网站隔离功能,这样每个跨站点的iframe都会拥有一个独立的渲染进程。

<p align="center">网站隔离功能会让跨站的iframe拥有独立的进程</p>

网站隔离技术汇聚了咱们工程师好几年的研发努力,它其实远远没有想象中那样只是为不一样站点的iframe分配一个独立的渲染进程那么简单,由于它从根本上改变了各个iframe之间的通讯方式。网站隔离后,对于有iframe的网站,当用户打开右边的devtool时,Chrome浏览器其实要作不少幕后工做才能让开发者感受不出这和以前的有什么区别,这实际上是很难实现的。对于一些很简单的功能,例如在devtool里面用Ctrl + F键在页面搜索某个关键词,Chrome都要遍历多个渲染进程去完成。因此咱们的浏览器工程师在网站隔离这个功能发布后都感叹这是一个里程碑式的成就。

总结

在本篇文章中,咱们探讨了浏览器高层次的架构设计以及多进程架构的带来的好处。同时咱们还讨论了服务化和网站隔离这些和浏览器多进程架构息息相关的技术。在下一篇文章中咱们要开始深刻了解这些进程和线程是如何呈现咱们的网站页面的了。

持续关注个人技术动态

我是进击的大葱,关注我和我一块儿进步成独当一面的全栈工程师!

文章首发于:窥探现代浏览器架构(一)

关注个人我的公众号获取个人最新技术推送!

相关文章
相关标签/搜索