一、当你点击打开 Chrome 时,发生了什么?
当你双击 Chrome 图标,操作系统会启动一个主进程(Browser Process) ,这是整个浏览器的“大脑”。这个进程拥有唯一的 PID(Process ID),负责:
- 管理浏览器 UI(地址栏、书签、标签页等)
- 协调子进程的创建与通信
- 提供存储服务(如 Cookie、LocalStorage 的读写)
💡 进程 vs 线程
- 进程:操作系统分配资源的最小单位,彼此隔离,崩溃互不影响。
- 线程:CPU 执行程序的最小单位,同一进程内的线程共享内存。
这里的代码 数据 文件是操作系统为进程分配的虚拟内存空间
“代码”、“数据”、“文件” 是什么?
| 名称 | 含义 | 是否在内存中? |
|---|---|---|
| 代码 | 程序的机器码或字节码(如 JS 被 V8 编译后的字节码) | ✅ 是,加载到内存中运行 |
| 数据 | 变量、对象、数组等运行时数据 | ✅ 是,存储在堆栈中 |
| 文件 | 外部资源(如 HTML、CSS、JS 文件) | ⚠️ 加载后进入内存,未加载前在磁盘 |
💡 所有这些内容,在程序运行时都会被加载到内存中,由操作系统为该进程分配一块独立的虚拟地址空间。
二、为什么选择 Chrome?市场与架构的双重胜利
Chrome 自 2008 年发布以来,凭借其稳定性、速度和安全性迅速占领市场(截至 2025 年,全球桌面浏览器占有率超 65%)。其核心优势之一,正是多进程架构——这正是我们今天要深挖的重点。
三、Chrome 的多进程架构详解
Chrome 并非单一进程,而是由多个独立进程协同工作组成。典型场景下(打开一个网页),你会看到以下进程:
| 进程类型 | 职责说明 |
|---|---|
| Browser 进程 | 主控进程,管理 UI、子进程调度、存储等 |
| Renderer 进程 | 每个标签页默认一个,负责 HTML/CSS 渲染 + JS 执行(Blink + V8) |
| GPU 进程 | 利用显卡加速页面合成、3D 变换(如 transform: translate3d) |
| Network 进程 | 统一处理所有网络请求(HTTP/HTTPS、WebSocket 等) |
| Utility / Plugin 进程 | 处理扩展(Extensions)、Flash(已淘汰)等插件 |
📌 关键设计思想:隔离性 > 内存开销
虽然每个标签页独立进程会消耗更多内存,但换来的是:
- 一个页面崩溃 ≠ 整个浏览器崩溃(IE 时代的噩梦终结)
- 安全沙箱:恶意网页难以访问其他页面或系统资源
四、渲染进程:HTML/CSS/JS 的执行舞台
每个标签页对应一个 Renderer 进程,内部包含两大核心引擎:
- Blink:排版引擎,解析 HTML/CSS,构建 DOM 树、样式树、布局、绘制。
- V8 引擎:执行 JavaScript,高性能 JIT 编译器。
⚠️ 重要澄清:JS 是“单线程”,但不是“唯一线程”
- 主线程(Main Thread) :负责执行 JS、样式计算、布局、绘制等。JS 代码在此单线程中同步执行。
- 其他辅助线程:如 Compositor Thread(合成)、Raster Thread(光栅化)等,用于提升渲染性能,但不执行用户 JS。
✅ 所以,“JS 是单线程”指的是:你的业务逻辑只能在一个线程中顺序执行,避免竞态条件。
五、事件循环(Event Loop):单线程如何处理异步?
尽管 JS 主线程是单线程,但通过 Event Loop + 异步任务队列 实现非阻塞 I/O:
js
编辑
// 同步任务(立即执行)
console.log('A');
// 异步任务(放入任务队列)
setTimeout(() => console.log('B'), 0);
// 微任务(优先级更高)
Promise.resolve().then(() => console.log('C'));
// 输出:A → C → B
- 宏任务(Macrotask) :
setTimeout、fetch回调等 - 微任务(Microtask) :
Promise.then、queueMicrotask
🔁 Event Loop 不断检查调用栈是否为空,空则依次执行微任务 → 宏任务。
六、对比:单进程浏览器(如 IE) vs 多进程(Chrome)
| 特性 | IE(单进程) | Chrome(多进程) |
|---|---|---|
| 稳定性 | ❌ 一个页面崩溃,全挂 | ✅ 页面隔离,崩溃不影响其他 |
| 安全性 | ❌ 插件/脚本可访问全局内存 | ✅ 沙箱机制,权限受限 |
| 内存占用 | ✅ 较低 | ❌ 较高(但现代硬件可承受) |
| 并发能力 | ❌ 所有操作共享一个线程池 | ✅ 网络、GPU、渲染并行处理 |
💬 历史教训:IE 的“全家桶崩溃”是推动多进程架构普及的关键动因。
七、常见疑问解答
Q1:为什么每个标签页都要独立进程?
- 隔离崩溃风险
- 安全沙箱(防止跨站脚本窃取数据)
- 更精准的资源回收(关闭标签即释放整个进程内存)
Q2:能否减少进程数节省内存?
- Chrome 提供 Site Isolation 策略:同站点页面可共享进程(需满足安全策略)
- 用户可通过
chrome://flags调整,但不建议普通用户修改
Q3:Web Worker 是多线程吗?
- ✅ 是!但不能操作 DOM,仅用于计算密集型任务(如图像处理、加密)
- 与主线程通过
postMessage通信,属于多线程协作,而非替代主线程
八、总结要点(速记卡片)
✅ Chrome = 多进程架构
✅ 每个标签页 ≈ 1 个 Renderer 进程(含 Blink + V8)
✅ JS 执行在主线程(单线程),但浏览器整体是多线程/多进程
✅ 崩溃隔离、安全沙箱、并行加载 = 多进程的核心价值
✅ Event Loop 让单线程也能高效处理异步