🙋 本文全长 20 分钟 , 市场价值¥ xxx9.9 元, 建议在时间充裕下进行详细阅读。chrome
🈯️ 读本章节内容中,带着如下三个问题进行阅读,更加有助于理解浏览器
Problem1 : 打开一个页面须要启动进程的配比是什么?<br/>
Problem2 : 为什么浏览器要使用多进程架构设计?<br/>
Problem3 : 多进程架构为什么仍会因为单页面卡死致使全部页面崩溃?<br/>安全
若是想要设计高性能 Web 应用,仍是要优化现有的 Web 应用,<br/>
都须要了解浏览器中的网络流程、页面渲染过程,JavaScript 执行流程,以及 Web 安全理论。网络
在本文中,全部的分析都是基于 Chrome 浏览器的。<br/>
由于 Chrome、微软的 Edge 以及国内的大部分主流浏览器,都是基于 Chromium 二次开发而来;<br/>
再加上 Chrome 是目前世界上使用频率较高的浏览器,因此 Chrome 具备表明性。多线程
在开始以前,咱们一块儿看下,Chrome 打开一个页面须要启动多少进程?你能够点击 Chrome 浏览器右上角的“选项”菜单,选择“更多工具”子菜单,点击“任务管理器”,这将打开 Chrome 的任务管理器的窗口,以下图:架构
那打开一个页面须要启动 7 个进程?其实不是的。工具
图片里的扩展程序:Dark Reader 这个是我本机安装的适用于任何网站的黑暗主题扩展程序,因此也占用了进程;<br/>
实用程序:Audio Service 是用于处理音频的,也并不是是必定要使用的。<br/>
Storage Service 即便页面未启用 WebStorage, 该进程也会启动并得到内存空间分配, 不过此时 CPU 占用为 0.0性能
在解答这个问题以前,咱们须要了解一下进程的概念,由于好多人容易把进程和线程的概念混淆,<br/>
因此这里就将这两个概念以及它们之间的关系一并讲解下。优化
在介绍进程和线程以前,须要先讲解下什么是并行处理。<br/>
若是你理解了并行处理的概念,那么再理解进程和线程之间的关系就会变得轻松许多。<br/>网站
计算机中的并行处理就是同一时刻处理多个任务。<br/>
<br/>
🌰 举个例子:咱们要计算下面这三个表达式的值,并显示出结果<br/>
A = 6+6 B = 6/6 C = 6*6
🚴 正常状况下程序可使用 单线程 来处理,也就是分四步按照顺序分别执行这 四个 任务<br/>
任务 1 是计算 A=6+6; 任务 2 是计算 B=6/6; 任务 3 是计算 C=6*6; 任务 4 是显示最后计算的结果。
🚗 采用多线程,会怎么样呢?<br/>
咱们只需分“两步走”:第一步,使用三个线程同时执行前三个任务;<br/>
第二步,再执行第四个显示任务
经过对比分析,你会发现用 🚴 单线程执行须要四步,而使用 🚗 多线程只须要两步。所以,使用并行处理能大大提高性能。
多线程能够并行处理任务,可是线程是不能单独存在的,它是由进程来启动和管理的。那什么又是进程呢 💡 ?
一个进程就是一个程序的运行实例。(话很少说,上图)
能够看到,线程是依附于进程的,而进程中使用多线程并行处理能提高运算效率。
总结来讲,进程和线程之间的关系有如下 4 个特色 (🔎 这里不作详细介绍,感兴趣的能够自查资料)<br/>
1.进程中的任意一线程执行出错,都会致使整个进程的崩溃。 2.线程之间共享进程中的数据。(线程之间能够对进程的公共数据进行读写操做) 3.当一个进程关闭以后,操做系统会回收进程所占用的内存。(即便其中任意线程由于操做不当致使内存泄漏,内存也会被正确回收) 4. 进程之间的内容相互隔离。(只能访问本身占有的数据,也就避免出现进程 A 写入数据到进程 B 的状况)
了进程和线程以后,咱们再来一块儿看下单进程浏览器的架构。。<br/>
顾名思义,单进程浏览器是指浏览器的全部功能模块都是运行在同一个进程里,这些模块包含了网络、插件、JavaScript 运行环境、渲染引擎和页面等。
如此多的功能模块运行在一个进程里,是致使单进程浏览器不稳定、不流畅和不安全的一个主要因素。<br/>
分析下出现问题的缘由<br/>
1:不稳定 ❌<br/>
早期浏览器须要借助于插件来实现诸如 Web 视频等各类强大的功能,可是插件是最容易出问题的模块,而且还运行在浏览器进程之中,因此一个插件的意外崩溃会引发整个浏览器的崩溃。
2:不流畅 ❌<br/>
从上图能够看出,全部页面的渲染模块、JavaScript 执行环境以及插件都是运行在同一个线程中的,这就意味着同一时刻只能有一个模块能够执行<br/>
function star() { while (true) { console.log("什么是快乐星球?"); } } star();
若是建立一个无限循环的脚本,运行在一个单进程浏览器的页面里,你感受会发生什么?<br/>
由于这个脚本是无限循环的,当其执行时它会独占整个线程,致使其余运行在该线程中的模块就没有机会被执行,结果就是整个浏览器失去响应,变卡顿。
3:不安全 ❌<br/>
这里能够从插件方面来解释该缘由。<br/>
插件可使用 C/C++ 等代码编写,经过插件能够获取到操做系统的任意资源,当你在页面运行一个插件时也就意味着这个插件能彻底操做你的电脑。若是是个恶意插件,那么它就能够释放病毒、窃取你的帐号密码,引起安全性问题。
以上这些就是单进程架构浏览器的特色,不稳定,不流畅,并且不安全。你能够想象一下这样的场景:当你正在用浏览器打开多个页面时,忽然某个页面崩溃了或者失去响应,随之而来的是整个浏览器的崩溃或者无响应,而后你发现你给老板写的邮件页面也随之消失了,这时你的心情会不会和页面同样崩溃呢?
从图中能够看出,最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程。
咱们来逐个分析下这几个进程的功能。<br/>
1.📒 浏览器进程。主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。<br/>
因为进程是相互隔离的,因此当一个页面或者插件崩溃时,影响到的仅仅是当前的页面进程或者插件进程,并不会影响到浏览器和其余页面,这就完美地解决了页面或者插件的崩溃会致使整个浏览器崩溃,也就是不稳定的问题。 不稳定问题得以解决 ✅
2.📒 渲染进程。核心任务是将 HTML、CSS 和 JavaScript 转换为用户能够与之交互的网页,默认状况下,Chrome 会为每一个 Tab 标签建立一个渲染进程。<br/>
JavaScript 也是运行在渲染进程中的,因此即便 JavaScript 阻塞了渲染进程,影响到的也只是当前的渲染页面,而并不会影响浏览器和其余页面,由于其余页面的脚本是运行在它们本身的渲染进程中的。因此当咱们再在 Chrome 中运行上面那个死循环的脚本时,没有响应的仅仅是当前的页面。 不流畅问题得以问题 ✅
出于安全考虑,渲染进程都是运行在沙箱模式下。
能够把沙箱当作是操做系统给进程上了一把锁,沙箱里面的程序能够运行,可是不能在你的硬盘上写入任何数据,也不能在敏感位置读取任何数据,例如你的文档和桌面。 Chrome 把插件进程和渲染进程锁在沙箱里面,这样即便在渲染进程或者插件进程里面执行了恶意程序,恶意程序也没法突破沙箱去获取系统权限。 安全问题得以解决 ✅
3.📒 GPU 进程。GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器广泛的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。<br/>
4.📒 网络进程。主要负责页面的网络资源加载,以前是做为一个模块运行在浏览器进程里面的,后来成为一个单独的进程。<br/>
5.📒 插件进程。主要是负责插件的运行,因插件易崩溃,因此须要经过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面形成影响。<br/>
6.📒 实用进程 AudioService 是用于处理音频的,也并不是是必定要使用的。
7.📒 实用进程 StorageService 是用于处理本地存贮的,包括 Storage(LocalStorage、SessionStorage)、Cache(CacheStorage、ApplicationCache)。
<br/>
✨ ✨ ✨ ✨ ✨ ✨ ✨✨✨✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨✨✨✨<br/>
✨ 讲到这里,就能够回答文章开头提到的前两个问题了 ✨<br/>
✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨✨✨✨✨✨
<br/>
1. 一个浏览器进程 + 1个GPU进程 + 1个网络进程 + 1个?渲染进程 + 多个插件进程 + StorageService 至少有6个进程启动: 浏览器主进程、GPU进程、NetworkService、当前标签页渲染进程、插件进程、StorageService 若是有音视频场景的话 还需加载 AudioService场景 2. 单进程架构浏览器的特色不稳定,不流畅,不安全,都被多进程架构解决处理 (凡事都有两面性,提高的同时也带来一些问题,更高的资源占用、更复杂的体系架构)。
问题讲解以前,要先讲一下打开 Tab 页时 是“1 个”渲染进程 仍是“多个”渲染进程?<br/>
<br/>
先了解下什么是同一站点(same-site)。<br/>
具体地讲,咱们将“同一站点”定义为根域名(例如,firstleap.cn)加上协议(例如,https:// 或者 http://),还包含了该根域名下...
https://wukong.firstleap.cn https://www.firstleap.cn https:///www.firstleap.cn:8080
🆚 Chrome 的默认策略(process-per-site-instance)是每一个标签对应一个渲染进程。但若是从一个页面打开了另外一个新页面,而新页面和当前页面属于同一站点的话,那么新页面会复用父页面的渲染进程。
🆚 若新页面和当前页面不属于同一站点 , 好比我经过掘金页面里的连接打开 InfoQ 的官网(https://www.infoq.cn/ ), 由于 infoq.cn 和 juejin.cn 不属于同一站点,因此 infoq.cn 会使用一个新的渲染进程。
总结 : A: 一般状况下,打开新的页面都会使用单独的渲染进程; B: 若是从 A 页面打开 B 页面,且 A 和 B 都属于同一站点的话,那么 B 页面复用 A 页面的渲染进程;
所以,当多个页面属于同一站点,共享一个渲染进程,当某个页面崩溃的时候,也将致使同一站点的其余页面也崩溃。