30 浏览器进程

Review

  1. 2024-10-05 14:47

[!Summary] 进程与线程关系,详见[[进程与线程]]

浏览器核心进程:

  1. 浏览器主进程
  2. 渲染进程
  3. GPU进程
  4. 网络进程
  5. 插件进程

常用浏览器

  1. Chrome
  2. Firefox
  3. Edge
  4. Safari
  5. Opera

一些浏览器(如Chrome和Firefox)会在后台静默更新,不提示用户,称之为evergreen浏览器

一、Introduction #

Chrome浏览器的多进程架构,主要进程包括

  1. 浏览器主进程
  2. 渲染进程
  3. GPU进程
  4. 网络进程
  5. 插件进程
  • 浏览器进程(Browser Process):
    • 负责用户界面、地址栏、书签等。
    • 管理其他进程,如渲染进程、插件进程等。
    • 处理文件下载、打印等操作。
    • 提供存储功能
  • 渲染进程(Renderer Process)
    • ==每个标签页通常对应一个渲染进程==。
    • 负责将HTML、CSS和JavaScript转换为可视化的网页。
    • 运行网页中的JavaScript代码。
  • GPU进程:
    • 负责硬件加速,如3D图形渲染、网页动画等。
    • 将渲染进程生成的合成帧提交给GPU进行渲染。
  • 网络进程:
    • 负责接收来自渲染进程的请求消息,并执行实际的网络请求。负责网络资源的加载,如图片、字体、脚本、fetch等。网络进程会将请求结果(响应数据)封装成消息,发送回渲染进程。
    • 优化网络请求,提高网页加载速度。
  • 插件进程:
    • 运行浏览器插件。
    • 每个插件通常运行在独立的进程中,以提高安全性。

每个渲染进程都运行在沙箱中,限制了插件和网页的权限,防止恶意代码损害整个系统。

渲染进程 #

渲染进程 核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。

渲染进程包含的线程 #
  1. 主线程(GUI渲染线程)
  2. JavaScript引擎线程
  3. 定时器触发线程
  4. 事件触发线程
  5. 异步HTTP请求线程
  6. 合成线程
  7. 栅格化线程
  • 主线程(GUI渲染线程) -> ==Blink渲染引擎==
    • 负责渲染页面,解析HTML、CSS,构建DOM树、CSSOM树、Render Tree、Layout Tree、Paint Tree
    • 执行JavaScript代码
    • 更新DOM和重新渲染、页面重绘重排时,该线程就会执行
    • 与用户交互,处理用户输入
    • 与JS引擎线程互斥,防止渲染结果不可预期
    • 是渲染进程的核心线程,大部分工作在主线程上完成
  • 合成线程
    • 接收 Paint Tree,将页面分割成多个图层(Layers),按照正确的顺序合并成一个或多个图层。每个图层包含了绘制指令和相关数据。
    • 负责页面平滑滚动和动画效果,不阻塞主线程。
  • 栅格化(Raster)线程
    • 将图层转换为位图
    • 将位图提交给GPU进程,GPU将位图显示在屏幕上
  • JS引擎线程 -> ==V8 JS引擎==
    • 负责处理解析和执行JavaScript代码
    • 只有一个JS引擎线程(单线程)
    • 与GUI渲染线程互斥,防止渲染结果不可预期
  • 事件触发线程
    • 用来控制事件循环(鼠标click、setTimeout cb、AJAX cb等)
    • 当事件满足触发条件时,将事件放入到JS引擎所在的执行队列中
  • 定时器触发线程
    • setInterval与setTimeout所在的线程
    • 定时任务并不是由JS引擎计时的,是由定时触发线程来计时的
    • 计时完毕后,通知事件触发线程
  • 异步HTTP请求线程
    • 浏览器有一个单独的线程用于处理 XMLHttpRequest, fetch 请求,该线程会将请求封装成消息,发送给网络进程。渲染进程执行实际的网络请求,将请求结果(响应数据)封装成消息,发送回渲染进程。
    • 当请求完成时,若有回调函数,通知事件触发线程
主线程和JS引擎线程都可以执行JavaScript代码,区别是什么? #

执行JavaScript代码的时机

  • 主线程:当遇到<script>标签或通过DOM操作动态添加的脚本时,会暂停当前的渲染任务,将控制权交给JavaScript引擎线程,执行完JavaScript代码后再继续渲染。
  • JavaScript引擎线程:由主线程调度,当遇到<script>标签或其他需要执行JavaScript代码的事件时,主线程会将控制权交给JavaScript引擎线程。
为什么 GUI 渲染线程与 JS 引擎线程互斥? #

主线程和JS引擎线程互斥的原因正是因为它们都可能操作DOM。如果两个线程同时操作DOM,就会导致数据不一致或者页面渲染混乱。为了保证DOM操作的顺序性和正确性,浏览器采用了单线程模型,即同一时间只能有一个线程操作DOM。

具体来说,当JavaScript代码执行DOM操作时,会发生以下过程:

  1. JS引擎线程解析并执行JavaScript代码,遇到DOM操作时,将这些操作添加到一个任务队列中。
  2. 主线程在空闲时会从任务队列中取出DOM操作任务,并更新DOM。

二、面向服务的架构 #

面向服务的架构 (Service-Oriented Architecture, SOA) 是一种软件设计方法,它将应用程序分解为一系列独立的服务。每个服务都提供特定的功能,并通过定义好的接口与其他服务进行通信。SOA 的核心思想是将应用功能模块化,提高系统的灵活性和可维护性

为了解决更高的资源占用以及更复杂的体系架构的问题,在 2016 年,Chrome 官方团队使用“面向服务的架构”(Services Oriented Architecture,简称 SOA)的思想设计了新的 Chrome 架构。也就是说 Chrome 整体架构会朝向现代操作系统所采用的“面向服务的架构” 方向发展,原来的各种模块会被重构成独立的服务(Service),每个服务(Service)都可以在独立的进程中运行,访问服务(Service)必须使用定义好的接口,通过IPC来通信,从而构建一个更内聚、松耦合、易于维护和扩展的系统,更好实现 Chrome 简单、稳定、高速、安全的目标。

理解: 以前是每个页面需要若干进程完成各自的工作,现在是将各个页面通用的功能(视频、网络、渲染等)发布为系统服务,页面在需要的时候与相应的服务通信完成需要的功能。这起码把进程间的耦合从页面中分离出去了。如下图所示:

Reference #

浏览器进程 深入浏览器中的进程与线程