浏览器:进程与线程

402 阅读7分钟

浏览器:进程与线程
浏览器:帧原理&渲染优化的基石
浏览器:安全策略

需要注意的是,浏览器的进程&线程架构属于实现细节,可能随着时间而变化,所以重在理解而不要死记硬背

进程定义:

进程是操作系统分配资源(如CPU时间、内存等)的基本单位,它包含了运行程序所需要的所有资源。每个进程都有自己独立的内存空间,进程之间的数据不共享,因此进程之间的通信(IPC,Inter-Process Communication)需要特殊的机制。

线程定义

线程是进程内的一个执行单元,是CPU调度和分派的基本单位。一个进程可以包含多个线程,这些线程共享进程的资源,可以并发执行。线程之间可以直接通信,因为它们共享同一块内存空间。

浏览器的进程&线程

如何查看浏览器有多少个进程:

截屏2023-12-29 下午3.40.58.png

结果分析:

process.png

1:主进程/浏览器进程(browser process):

功能:负责浏览器界面显示、用户交互、子进程管理等功能

2:gpu进程:

功能:负责处理浏览器的渲染任务,多进程共享,负责将帧渲染到显示器上

3:渲染进程(render process):

功能:负责把HTML、CSS和JavaScript转化为用户可以交互的网页,渲染引擎和JavaScript引擎都是运行在该进程中。默认情况下,浏览器会为每个Tab标签创建一个进程。出于安全和稳定性考虑,渲染进程都是运行在沙箱模式下。

  • gui线程:解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等,当界面需要重绘或由于某种操作引发回流时,该线程就会执行
  • js引擎线程:解释执行js代码
  • 计时器线程:执行计时器任务
  • 事件线程:负责处理如页面滚动、点击等事件,捕获任务回调,放入事件队列里,等待js执行
  • 合成线程:将多个层合并为一帧交给gpu渲染,css中的动画属性和transform属性都是作用在这个线程中的。

gui线程/js引擎线程 因为两者互斥且都可以更改UI,所以都可以理解为渲染进程的主线程, 其他线程是辅助主线程工作的也可统称为工作线程,至于工作线程的具体的数量或名字,这个根据浏览器的实现可能有所不同

4:网络进程:

处理页面的网络请求,以及管理多个web socket和HTTP/2连接。

5:插件进程:

功能:负责控制网页使用到的插件

6:存储进程:应该是新增的

功能:负责访问文件,管理浏览器的存储等

进程交互图:

用户输入url后到页面内容渲染完成的过程中涉及到的主要进程和线程交互:

截屏2024-01-03 上午10.53.15.png

浏览器主进程:

当用户在地址栏输入URL并按下回车后,浏览器主进程会接收到这个输入,并负责启动网络进程进行网络请求。

网络进程:

网络进程接收到浏览器主进程的请求后,会创建一个网络请求线程,这个线程会根据URL进行DNS查询(如果需要),建立TCP连接,发送HTTP请求,接收服务器的HTTP响应。

渲染进程:

浏览器主进程会为每个Tab标签创建一个渲染进程。当网络进程接收到服务器的HTTP响应后,会将响应数据发送给对应的渲染进程。渲染进程中的主线程会解析HTML、CSS和JavaScript,生成DOM树和CSSOM树,然后进行布局和绘制,最终将渲染结果显示在屏幕上。

  1. 渲染进程的主线程在解析HTML并构建DOM树的过程中,如果遇到<link><script><img>等标签,会发现需要下载额外的静态资源。
  2. 主线程会将这些资源的URL发送给网络进程。
  3. 网络进程接收到URL后,会创建一个新的网络请求线程,这个线程会进行DNS查询(如果需要),建立TCP连接,发送HTTP请求,接收服务器的HTTP响应。
  4. 当网络进程接收到服务器的响应数据后,会将数据发送回渲染进程。
  5. 渲染进程的主线程接收到数据后,会根据资源的类型进行相应的处理。例如,如果是CSS文件,主线程会解析CSS并构建CSSOM树;如果是JavaScript文件,主线程会解析并执行JavaScript代码;如果是图片,主线程会将图片数据发送给GPU进程进行渲染。

GPU进程:

在页面渲染过程中,如果有GPU加速的操作,如CSS的3D变换,这些操作会被发送到GPU进程,由GPU进程来进行处理。

相关问题:

即使是如今的多进程架构,我偶尔还会碰到一些由于单个页面卡死最终崩溃导致所有页面崩溃的情况,请问这是什么原因呢?

Chrome的默认策略是,每个标签对应一个渲染进程。但是如果从一个页面打开了新页面,而新页面和当前页面属于同一站点时,那么新页面会复用父页面的渲染进程。官方把这个默认策略叫process-per-site-instance。所以,这种情况下,一个页面崩溃了,会导致同一站点的页面同时崩溃,因为他们使用了同一个渲染进程。
为什么要让他们跑在一个进程里面呢?
因为在一个渲染进程里面,他们就会共享JS的执行环境,也就是说A页面可以直接在B页面中执行脚本。因为是同一家的站点,所以是有这个需求的。

浏览器还有哪些进程模型

  1. Single-process:单进程模式。一个浏览器只有一个进程,这种模型的优点是资源消耗最小,但是稳定性和安全性较差,任何一个部分出现问题都可能导致整个浏览器崩溃。
  2. Process-per-tab:每个标签页一个进程。这种模型的优点是每个标签页都是独立的,一个标签页出现问题不会影响其他标签页,但是会消耗更多的系统资源。
  3. Process-per-site:每个站点一个进程。这种模型的优点是可以减少进程的数量,因为同一个站点的所有标签页都在同一个进程中运行。但是,如果一个标签页出现问题,可能会影响到同一个站点的其他标签页。
    举个例子解释下:例如有两个标签页,它们都是来自同一个网站(例如:www.example.com),如果浏览器采用的是Process-per-site模型,那么这两个标签页会在同一个进程中运行。也就是说,浏览器会为www.example.com 这个站点创建一个进程,然后在这个进程中运行所有来自这个站点的网页。所以,无论你打开了多少个来自www.example.com 的标签页,它们都会在同一个进程中运行。
  4. process-per-site-instance 默认模式:上面介绍过的,如果从一个页面打开了新页面,而新页面和当前页面属于同一站点时,那么新页面会复用父页面的渲染进程.
    举个例子解释下:例如有两个标签页,它们都是来自同一个网站(例如:www.example.com), 它们也可能在不同的进程中运行,除非它们之间存在上下文关系(例如从a网页到b网页,通过JavaScript进行通信)。

参考

  1. developer.chrome.com/blog/inside…
  2. zhuanlan.zhihu.com/p/362120843