|
概念 |
- 进程是cpu资源分配的最小单位,也是独立运行的最小单位(一个进程就是一个程序的运行实例)
- 线程是cpu调度的最小单位(线程是不能单独存在的,它是由进程来启动和管理的,一个进程中可以有多个线程,进程内的线程共享进程全部资源)
单线程VS多线程 |
- 单线程:事情只能做完一件再做下一件事(要是发起请求资源,很久才有回应,也只能这么耗着)
- 多线程:只作单处理器情况下的说明(虽有多核浏览器,但实时处理着线程的只有单个核),A线程进行耗时请求,那我不等你返回,切到B线程,先执行B了,这样就提高了整体运行效率。(实际没有这么简单,要进行时间分片,状态监控等等)
|
单进程浏览器是指浏览器的所有功能模块都是运行在同一个进程里,这些模块包含了网络、插件、JavaScript 运行环境、渲染引擎和页面等。早在 2007 年之前,市面上浏览器都是单进程的,现在市面上浏览器基本都是多进程的了。
所有功能模块放在一个进程里面,是导致单进程浏览器不稳定、不流畅和不安全的主要原因。
- 不稳定
举个🌰:进程里面的某关键功能崩了,那就不是这个网页打不开的问题了,而是整个浏览器都炸了。 - 不流畅
举个🌰:所有页面的渲染模块、JavaScript 执行环境以及插件都是运行在同一个线程中的。假如JS正在处理一个耗时计算,当其执行时,它会独占整个线程,这样导致其他运行在该线程中的模块就没有机会被执行,这样就会导致整个浏览器失去响应,变卡顿。 - 不安全
举个🌰:插件可以使用 C/C++ 等代码编写,插件也是浏览器功能模块,和其他模块共享进程资源,
通过插件可以获取到操作系统的任意资源。
|
每打开一个新页面就会创建一个进程,当然也会有些优化策略,如果同时打开多个空白页,会将多个空白页合并为一个进程。
查看浏览器进程 |
步骤:谷歌浏览器->更多工具->任务管理器。
下图你可以确切的看到浏览器当前运行的各个进程
默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。但是我们也能看到有几个标签页共用一个进程,这其实是浏览器的优化机制,将某些同域名下的进程合并为一了。 👉渲染进程不一定每个Tab就一个
浏览器中主要的进程 |
从图中可以看出, Chrome(版本 81) 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、1个音频(Audio)进程、多个渲染进程和多个插件进程。
- 浏览器进程:浏览器的主进程(负责协调、主控)
+ 负责浏览器界面显示,与用户交互。网址栏输入、前进、后退等
+ 管理各个页面,创建和销毁进程
+ 将页面内容(位图)写入到浏览器内存中,最后再将图像显示在屏幕上
+ 文件储存等功能 - 渲染进程:默认一个Tab页面一个渲染进程(特殊情况:渲染进程不一定每个Tab就一个)
+ 页面渲染
+ 脚本执行
+ 事件处理等 - GPU进程:用于3d绘制等,将开启了3d绘制的元素的渲染由CPU转向GPU,也就是开启GPU加速。
- 网络进程:主要负责页面的网络资源加载,之前是作为一个模块(NetWork Thread)运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。
- 插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建
- 音频进程:浏览器音频管理
不同进程负责的浏览器区域示意图
浏览器内核 指的是渲染引擎,以前可以分成两部分:渲染引擎和JS引擎,后来JS引擎独立出来了。
服务类进程是常驻的 对某服务进程点击了结束进程,它也会立即重启或在你刷新页面时重启。
以Audio Service为例,你打开某页面在播放音频或视频的时候,直接结束了Audio Service进程,你会发现Audio Service瞬间消失又启动了,与此同此,视频暂停了,点击继续播放也没用,需要刷新页面后才可以正常播放。
怎么证明谷歌浏览器页面是依赖于GPU绘制的呢(硬件加速模式开启的情况下)?
结束GPU进程瞬间你可以看到整个浏览器全黑屏,瞬间进程自动重启,浏览器恢复正常。
多进程浏览器的优势 |
与单进程浏览器相比:单进程浏览器的不足多进程浏览器都处理好了
- 避免单个页面或者插件崩溃影响整个浏览器
- 充分利用多核的优势
- 使用沙盒模型隔离插件等进程,提高浏览器稳定性
不足之处就是占用的内存多了(空间换时间)
浏览器内核(渲染进程) |
页面的渲染,JS的执行,事件的循环,都在这个进程内进行。
浏览器的渲染进程是多线程的,并非所有浏览器中渲染进程的线程划分都是一样的,谷歌浏览器总是走在浏览器发展的前沿,经常会更快迭代引领潮流。
非谷歌浏览器 |
GUI渲染线程与JS引擎线程是互斥的,不能一并执行。
这是避免页面渲染过程中,JS修改了DOM元素,使得页面呈现效果与预想不符。还有就是,假如JS在执行大规模的预算,那岂不是会将页面渲染卡住了吗?为此H5引进了Web Workers,web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。
❓JS为什么是单线程?
如果JS是多线程,假如有thread1和thread2两个线程同时操作同一个Dom元素,thread1删除该Dom元素,thread2修改该Dom元素,同时下达两个矛盾任务让浏览器怎么执行呢,这就是为什么JS被设计成单线程。
谷歌浏览器 |
谷歌浏览器官网提供的渲染进程里的线程图:
来源:Inside look at modern web browser (part 3)
- 主线程 Main thread
主线程中即可以执行 JS ,也可以执行渲染工作,还可以执行其他工作,但是由于是主线程是只是一个线程,所以各个工作不能同时执行,只能按照一定的先后次序执行。 MDN上有一个简单介绍: 主线程. - 工作线程 Worker thread
由 Worker 或 Service Worker 注册的 javascript 代码会有单独的 Worker 线程处理,独立于主线程。 - 排版线程 Compositor thread
页面平滑层次展示 - 光栅线程 Raster thread
页面快速呈现
基本而言,谷歌浏览器的主线程,操办了非谷歌浏览器中那五个线程的任务,且额外还新增了几个线程。
了解一下:谷歌新版浏览器渲染流程
📌 站点隔离-单独的渲染进程
站点隔离是 Chrome 最近推出的一个功能,它确保了每个跨站点的 iframe 都渲染在单独的进程中。
在 Chrome 67 版本之后,站点隔离将自动应用在跨站点的 iframe 上。保证了进网站间的独立性和安全性。
|
虽然多进程模型提升了浏览器的稳定性、流畅性和安全性,但同样不可避免地带来了一些问题:
- 更高的资源占用
- 更复杂的体系架构
浏览器各模块之间耦合性高、扩展性差,难适应新需求
在 2016 年,Chrome 官方团队使用“面向服务的架构”的思想设计了新的 Chrome 架构,为了构建一个更内聚、松耦合、易于维护和扩展的系统。
Chrome 把浏览器不同程序的功能看做服务,这些服务可以方便的分割为不同的进程或者合并为一个进程。以 Broswer Process 为例,如果 Chrome 运行在强大的硬件上,它会分割不同的服务到不同的进程,这样 Chrome 整体的运行会更加稳定,但是如果 Chrome 运行在资源贫瘠的设备上,这些服务又会合并到同一个进程中运行,这样可以节省内存,示意图如下。
参考文档: inside-browser-part1.