进程与线程
- 进程 (Process)
-
- 进程是操作系统分配资源(如内存、CPU)的基本单位,不同进程之间相互隔离,一个进程崩溃不会直接影响其他进程。
- 例子:Chrome 浏览器中,每个标签页、插件、网络请求等都可能运行在独立的进程中。
- 线程 (Thread)
-
- 线程是进程内的执行单元,共享进程的内存空间。多线程可以提高并发性能,但线程间缺乏隔离,一个线程崩溃可能导致整个进程崩溃。
浏览器多进程架构
为什么需要多进程架构?
在早期的单进程浏览器时代(如 IE 6),浏览器所有功能(页面渲染、网络请求、JavaScript 执行、插件运行等)都运行在同一个进程中。这种架构虽然简单,但存在诸多致命问题:
1. 稳定性差:一崩全崩
- 问题 :单进程中,页面渲染、插件或 JavaScript 的崩溃会导致整个浏览器崩溃。
- 示例 :一个 Flash 插件崩溃可能让用户丢失所有已打开的标签页。
- 用户痛点 :“我只是想关掉一个卡住的页面,结果整个浏览器都没了!”
2. 安全性低:漏洞扩散无阻
- 问题 :所有代码共享同一进程内存,恶意脚本或插件可轻易攻击浏览器核心功能(如窃取 Cookie 或文件)。
- 案例 :早期的浏览器漏洞常通过 JavaScript 直接读写用户磁盘。
3. 性能瓶颈:资源争抢严重
- 问题 :网络请求、页面渲染、UI 响应等任务在同一进程中竞争 CPU 和内存资源。
- 现象 :打开多个标签页时,浏览器卡顿明显,甚至出现“无响应”状态。
4. 扩展性差:难以利用多核 CPU
- 问题 :单进程只能使用单线程或有限线程,无法充分发挥多核硬件的优势。
- 后果 :随着网页复杂度提升(如 WebGL、视频解码),单进程架构性能捉襟见肘。
2008 年,Chrome 首次引入多进程架构,将浏览器拆分为多个独立进程,实现了隔离性 、并行化 和安全性 的飞跃。这种设计迅速成为现代浏览器的标准(如 Firefox 的 Project Fission、Edge 的进程模型)。
核心进程
| 进程名称 | 英文 | 功能描述 |
|---|---|---|
| 浏览器主进程 | Browser Process | 负责管理浏览器窗口、地址栏、书签、下载等全局功能,协调其他进程的创建和销毁 |
| 渲染进程 | Renderer Process | 每个标签页或 iframe 对应一个进程(同源策略下可能共享),负责页面 HTML/CSS/JS 解析、渲染和事件处理。 |
| GPU 进程 | GPU Process | 独立处理图形渲染任务(如 CSS 动画、WebGL),通过硬件加速提升性能,降低主进程负载。 |
| 网络服务进程 | Network Service Process | 统一管理所有网络请求(HTTP/WebSocket)、DNS 解析、缓存和 Cookie(自 Chrome 67 起独立为单独进程)。 |
| 扩展进程 | Extension Process | 每个浏览器扩展运行在独立进程中,防止恶意插件影响浏览器主进程或其他标签页。 |
| 实用进程 | Utility Process | 处理临时任务,如音视频解码(Utility: Audio Service)、文件解析(Utility: Data Decoder)等,完成后自动销毁 |
多进程架构的优势
1. 稳定性:进程隔离,崩溃可控
- 原理 :每个标签页运行在独立渲染进程中,崩溃仅影响当前标签。
- 用户价值 :
-
- 卡住的网页可以直接关闭,无需重启整个浏览器。
- 通过
chrome://crash可手动测试单个标签页崩溃的恢复能力。
- 技术实现 :
-
- 浏览器主进程监控子进程状态,自动重启崩溃的渲染进程。
2. 安全性:沙箱隔离,漏洞难逃
- 原理 :关键进程(如渲染进程、网络进程)运行在沙箱(Sandbox)中,权限被严格限制。
- 示例 :
-
- 渲染进程无法直接读写磁盘文件(需通过浏览器主进程代理)。
- 恶意代码无法通过渲染进程攻击操作系统。
- 技术实现 :
-
- 操作系统级隔离(如 Windows 的 Job 对象、Linux 的命名空间)。
3. 性能:多核并行,各司其职
- 原理 :不同进程可绑定到不同 CPU 核心,实现真正的并行计算。
- 场景优化 :
-
- GPU 进程 :专用于图形渲染,支持 3D 动画和 WebGL 高性能计算。
- 网络进程 :统一管理 TCP 连接池、DNS 缓存,减少重复请求开销。
- 数据佐证 :多进程架构下,Chrome 的页面加载速度和响应延迟显著优于早期单进程浏览器。
4. 资源管理:按需分配,动态调度
- 原理 :浏览器主进程统一协调资源分配,避免浪费。
- 策略举例 :
-
- 后台标签页冻结 :减少非活动标签页的 CPU 和内存占用。
- 进程复用 :同源网站共享渲染进程(可通过
chrome://process-internals查看)。
5. 扩展性:功能模块化,迭代更灵活
- 原理 :每个功能模块(如网络、存储、扩展)可独立升级或替换。
- 案例 :
-
- Chrome 的 Network Service 进程化后,网络层更新无需重启整个浏览器。
- Site Isolation 功能通过强化进程隔离,防御 Spectre 等硬件级漏洞。
浏览器导航与渲染
1. 输入阶段(浏览器主进程)
- 输入预处理
-
- 地址栏输入时,浏览器主进程的 UI线程 会先进行安全检查(如防止 XSS 攻击字符过滤)
- HSTS 检查 :强制 HTTPS(若域名在 HSTS 列表中,直接跳 HTTPS)
- 预连接优化 :Chrome 会对高频域名提前建立 TCP 连接(如搜索框输入时)
2. 网络请求阶段(网络进程)
- DNS 解析优化
-
- 浏览器缓存 → 本地 Hosts → DNS 预取(
<link rel="dns-prefetch">) → 递归查询 - DNS over HTTPS (DoH) :现代浏览器默认开启加密 DNS
- 浏览器缓存 → 本地 Hosts → DNS 预取(
- TCP 连接复用
-
- 检查是否有可用 Keep-Alive 连接(减少 3 次握手开销)
- 若启用 QUIC(HTTP/3),直接建立 UDP 连接
- 响应处理
-
- 内容嗅探(MIME Sniffing) :若
Content-Type缺失/错误,通过文件内容推断类型 - 安全校验 :
- 内容嗅探(MIME Sniffing) :若
-
-
- 跨域响应检查(CORS)
- CSP(Content Security Policy)验证
- 恶意内容扫描(如 Chrome 的 Safe Browsing)
-
3. 准备渲染进程(浏览器主进程)
- 进程分配策略
-
- Site Isolation :同源策略下同一站点(eTLD+1)复用进程
- 超过进程数限制时,LRU 策略回收旧进程
- 沙箱初始化
-
- 渲染进程启动后,立即启用沙箱(限制文件系统访问、系统调用等)
4. 渲染阶段(渲染进程主线程)
- 解析(Parse)
-
- 预解析扫描器(Preload Scanner) :提前发现 CSS/JS/图片等资源并触发加载
- DOM 构建 :遇到
<script>时,根据async/defer决定是否阻塞解析
- 样式计算(Style)
-
- 层叠上下文优化 :浏览器会缓存部分计算结果(如复用相同类名的样式)
- 布局(Layout)
-
- 增量布局 :仅重新计算受影响元素(如窗口 resize 时)
- CSS Containment :通过
contain: strict属性限制布局范围以优化性能
- 分层(Layer)
-
- 根据
will-change、transform等属性决定是否提升为独立合成层
- 根据
5. 合成与光栅化(渲染进程合成线程 + GPU 进程)
- 分块(Tiling)
-
- 视口附近的图块优先级更高(优先光栅化)
- 光栅化(Raster)
-
- GPU 加速 :使用 Skia(Chrome)或 Core Graphics(Safari)渲染 2D 图形
- 部分光栅化 :只渲染可见区域,滚动时动态加载
- Draw Quads
-
- 生成绘制指令(如纹理坐标),提交给 GPU 进程的 Command Buffer
6. 最终显示(浏览器主进程 + GPU 进程)
- 帧提交
-
- GPU 进程通过 OpenGL/Vulkan 接口提交到显示合成器(Display Compositor)
- 垂直同步(VSync)信号触发屏幕刷新
- 界面更新
-
- 浏览器主进程停止地址栏旋转图标,更新历史记录和页面标题