为什么一个标签页崩溃不会让整个浏览器卡死?——聊聊浏览器的多进程架构
引言你有没有遇到过这样的情况某个标签页突然卡住不动了但其他标签页依然可以正常浏览、切换为什么一个网页崩溃不会拖垮整个浏览器答案就藏在Chrome的多进程架构里。一、从“打开一个页面为什么有6个进程”说起打开Chrome的任务管理器点击右上角菜单 → 更多工具 → 任务管理器或者直接按 Shift Esc你会发现一件有趣的事情明明只打开了一个标签页任务管理器里却出现了好几个Chrome进程。一个页面为什么要启动这么多进程这得从浏览器的架构演进说起。在2007年以前市面上的浏览器基本都是单进程架构——所有的功能模块网络、插件、JS引擎、渲染引擎等都运行在同一个进程里。这种架构存在三大致命缺陷不稳定一个插件崩溃或者一个页面的脚本出错就会导致整个浏览器崩溃不流畅某个页面的死循环脚本会让整个浏览器卡死所有标签页都跟着遭殃不安全所有页面共享同一块内存恶意网页可以通过内存漏洞获取系统权限为了解决这些问题Google在2008年推出Chrome时率先采用了多进程架构。正如Chromium官方文档所说“构建一个永不崩溃或永不卡顿的渲染引擎几乎是不可能的构建一个绝对安全的渲染引擎也几乎是不可能的。”多进程架构的思路就是把每个网页放进独立的进程里就像现代操作系统把不同的应用程序隔离开一样。二、进程与线程先搞懂两个基础概念在深入之前我们先弄懂两个基础概念。进程Process 是操作系统资源分配的基本单位。启动一个程序时操作系统会为它创建一块独立的内存空间用来存放代码、运行中的数据。可以把它理解成一个 “工厂” ——每个工厂有自己独立的地盘和资源。线程Thread 是进程内的执行单元是CPU调度的最小单位。可以把它理解成工厂里的 “工人” ——同一个工厂里的工人共享工厂的资源内存但不同工厂的工人不能直接跑到别的工厂里去干活。进程和线程之间有几个关键特点进程中的任意一线程执行出错会导致整个进程崩溃不同进程之间相互隔离一个进程崩溃不影响其他进程不同进程无法直接访问彼此的内存数据同一个进程内的多个线程共享进程的内存空间这正是多进程架构能够实现“标签页隔离”的底层基础——一个渲染进程崩溃了其他进程完全不受影响。三、Chrome的五大核心进程现代Chrome浏览器采用 “1主N子” 的进程模型主要包括以下几类核心进程浏览器主进程Browser Process—— 总指挥浏览器主进程是整个浏览器的 “大脑”和“总指挥” 。它负责管理浏览器UI界面地址栏、书签、标签页等控制子进程的创建、管理和终止处理用户输入点击、键盘事件管理存储Cookie、localStorage等协调各个进程间的通信关键点浏览器主进程是Chrome中唯一具有高权限的进程可以直接访问操作系统资源。但它不直接渲染网页内容。渲染进程Renderer Process—— 每个标签页的独立战场渲染进程是前端开发者最需要关注的进程。每个标签页或站点默认对应一个独立的渲染进程。它的核心任务是将HTML、CSS和JavaScript转换为用户可以与之交互的网页。渲染进程内部运行着两大核心引擎Blink引擎负责解析HTML/CSS构建DOM树和CSSOM树V8 JavaScript引擎负责执行JavaScript代码出于安全考虑渲染进程运行在 “沙箱模式” 下权限受到严格限制无法直接访问操作系统资源。一个渲染进程内部也是多线程的主要包括主线程Main Thread 执行JS、构建DOM、样式计算、布局、生成绘制指令合成线程Compositor Thread 负责将图层合成并交给GPU渲染IO线程负责接收来自其他进程的IPC消息工作线程Worker Thread 运行Web Worker等后台任务GPU进程GPU Process—— 图形加速器Chrome刚发布时并没有独立的GPU进程。随着网页越来越复杂CSS 3D变换、WebGL、视频播放等场景大量使用GPUChrome于是将GPU操作独立成一个进程。GPU进程负责页面最终的绘制与合成处理WebGL、CSS 3D变换硬件加速视频解码将GPU操作隔离的好处是即使GPU驱动出现问题也不会导致整个浏览器崩溃。网络进程Network Process—— 网络请求大总管网络进程是后来才从浏览器进程中独立出来的。它专门负责所有HTTP/HTTPS请求DNS解析资源缓存管理Cookie管理连接池和HTTP/2多路复用安全优势即使某个页面被XSS攻击也无法直接操控网络层发起任意请求——所有网络请求都需要通过IPC通信。插件进程Plugin Process—— 插件的隔离舱插件如Flash、PDF阅读器是最容易出问题的模块。Chrome为每个插件单独创建一个进程这样即使插件崩溃也不会影响浏览器和其他页面。小贴士打开一个页面为什么至少需要4个进程因为至少需要1个浏览器进程 1个GPU进程 1个网络进程 1个渲染进程。如果页面还跑了插件还得加上插件进程。四、进程间如何通信——IPC与Mojo进程之间是相互隔离的那它们怎么协同工作呢答案是进程间通信IPC, Inter-Process Communication 。比如渲染进程需要加载一张图片流程是这样的渲染进程通过IPC发送请求给网络进程网络进程下载完成后通过IPC将数据传回渲染进程渲染进程再将数据交给合成线程最终显示到屏幕Chrome早期使用传统的IPC框架但随着浏览器功能越来越复杂传统IPC逐渐暴露出序列化开销大、类型安全不足、异步处理复杂等问题。为此Chrome团队开发了Mojo框架——一个现代化的跨进程通信解决方案。Mojo的优势包括强类型接口通过.mojom文件自动生成类型安全的代码异步消息传递原生支持回调适合高并发跨语言支持支持C、Java、JavaScript等安全与隔离每条管道可以设置权限Chromium官方文档也确认“浏览器和渲染器使用Mojo或Chromium的传统IPC系统进行通信。”五、多进程架构的三大优势回到文章开头的问题为什么一个标签页崩溃不会让整个浏览器卡死答案就在于多进程架构带来的三大优势稳定性进程之间相互隔离。当一个渲染进程崩溃时影响的仅仅是当前标签页浏览器主进程和其他标签页的渲染进程完全不受影响。这就是为什么你经常能看到Chrome弹出“噢唷崩溃啦”的提示但其他标签页依然安然无恙。安全性渲染进程运行在沙箱中无法直接访问操作系统资源。即使恶意网页利用了渲染进程的漏洞攻击者也无法突破沙箱获取系统权限。再加上站点隔离Site Isolation 技术——不同站点的网页被强制分配到不同的渲染进程中——进一步防御了Spectre等侧信道攻击。性能多进程架构可以充分利用多核CPU的并行处理能力。渲染、网络、GPU各司其职一个进程的繁忙不会阻塞其他进程。比如即使某个页面的JavaScript在主线程上执行耗时任务合成线程依然可以保证页面的滚动流畅。六、多进程并非完美——挑战与未来凡事都有两面性。多进程架构虽然带来了稳定性和安全性但也带来了新的挑战更高的资源占用每个进程都包含公共基础结构的副本如V8引擎消耗更多内存更复杂的体系架构模块之间耦合性高扩展性差为了解决这些问题Chrome团队从2016年开始探索面向服务的架构SOA 。其核心思想是将各种功能模块重构成独立的服务Service 每个服务都可以在独立的进程中运行服务之间通过定义好的接口和IPC通信。这种架构的优势在于弹性在性能强大的设备上服务以多进程方式运行充分发挥性能优势在资源受限的设备上多个服务可以合并到一个进程中运行节省内存。目前Chrome正处在从传统多进程架构向服务化架构过渡的阶段这将是一个漫长的迭代过程。总结Chrome的多进程架构本质上是用 “空间换稳定” ——用更多的内存开销换来更高的稳定性、安全性和性能。当一个标签页崩溃时其他标签页依然可以正常工作这正是多进程隔离带来的最直观的好处。理解浏览器的多进程架构不仅能帮你解答“为什么标签页崩溃不会卡死整个浏览器”这样的问题更能让你站在更高的维度去理解Web应用的性能优化、安全策略和渲染流程。