Review
- 2024-10-05 14:47
[!Summary] 进程与线程关系,详见[[进程与线程]]
浏览器核心进程:
- 浏览器主进程
- 渲染进程
- GPU进程
- 网络进程
- 插件进程
常用浏览器
- Chrome
- Firefox
- Edge
- Safari
- Opera
一些浏览器(如Chrome和Firefox)会在后台静默更新,不提示用户,称之为evergreen浏览器。
一、Introduction #

Chrome浏览器的多进程架构,主要进程包括
- 浏览器主进程
- 渲染进程
- GPU进程
- 网络进程
- 插件进程
- 浏览器进程(Browser Process):
- 负责用户界面、地址栏、书签等。
- 管理其他进程,如渲染进程、插件进程等。
- 处理文件下载、打印等操作。
- 提供存储功能
- 渲染进程(Renderer Process):
- ==每个标签页通常对应一个渲染进程==。
- 负责将HTML、CSS和JavaScript转换为可视化的网页。
- 运行网页中的JavaScript代码。
- GPU进程:
- 负责硬件加速,如3D图形渲染、网页动画等。
- 将渲染进程生成的合成帧提交给GPU进行渲染。
- 网络进程:
- 负责接收来自渲染进程的请求消息,并执行实际的网络请求。负责网络资源的加载,如图片、字体、脚本、
fetch等。网络进程会将请求结果(响应数据)封装成消息,发送回渲染进程。 - 优化网络请求,提高网页加载速度。
- 负责接收来自渲染进程的请求消息,并执行实际的网络请求。负责网络资源的加载,如图片、字体、脚本、
- 插件进程:
- 运行浏览器插件。
- 每个插件通常运行在独立的进程中,以提高安全性。
每个渲染进程都运行在沙箱中,限制了插件和网页的权限,防止恶意代码损害整个系统。
渲染进程 #
渲染进程 核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
渲染进程包含的线程 #
- 主线程(GUI渲染线程)
- JavaScript引擎线程
- 定时器触发线程
- 事件触发线程
- 异步HTTP请求线程
- 合成线程
- 栅格化线程
- 主线程(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操作时,会发生以下过程:
- JS引擎线程解析并执行JavaScript代码,遇到DOM操作时,将这些操作添加到一个任务队列中。
- 主线程在空闲时会从任务队列中取出DOM操作任务,并更新DOM。
二、面向服务的架构 #
面向服务的架构 (Service-Oriented Architecture, SOA) 是一种软件设计方法,它将应用程序分解为一系列独立的服务。每个服务都提供特定的功能,并通过定义好的接口与其他服务进行通信。SOA 的核心思想是将应用功能模块化,提高系统的灵活性和可维护性。
为了解决更高的资源占用以及更复杂的体系架构的问题,在 2016 年,Chrome 官方团队使用“面向服务的架构”(Services Oriented Architecture,简称 SOA)的思想设计了新的 Chrome 架构。也就是说 Chrome 整体架构会朝向现代操作系统所采用的“面向服务的架构” 方向发展,原来的各种模块会被重构成独立的服务(Service),每个服务(Service)都可以在独立的进程中运行,访问服务(Service)必须使用定义好的接口,通过IPC来通信,从而构建一个更内聚、松耦合、易于维护和扩展的系统,更好实现 Chrome 简单、稳定、高速、安全的目标。
理解: 以前是每个页面需要若干进程完成各自的工作,现在是将各个页面通用的功能(视频、网络、渲染等)发布为系统服务,页面在需要的时候与相应的服务通信完成需要的功能。这起码把进程间的耦合从页面中分离出去了。如下图所示:
