从架构演进视角看,浏览器经历了:
其核心目标始终围绕三个长期不变的约束展开:
本文从第一性原理与体系结构层面,系统性抽象浏览器的运行机制、能力模型与演进逻辑。
浏览器是一个面向不可信代码的、安全隔离的、事件驱动的、可视化计算平台。
其本质由四个不可分割的约束共同塑造:
| 约束维度 | 核心问题 |
|---|---|
| 安全 | 如何执行来自不可信来源的代码 |
| 并发 | 如何同时处理用户交互、渲染、网络、脚本 |
| 性能 | 如何在毫秒级响应中完成复杂计算 |
| 可视化 | 如何将抽象状态映射为图形输出 |
浏览器可被抽象为 “多引擎协同 + 事件循环驱动 + 分层渲染流水线” 的系统:
graph TD
User[用户输入]
Browser[浏览器进程]
Render[渲染进程]
JS[JS 引擎]
GPU[GPU/合成]
Screen[屏幕输出]
User --> Browser
Browser --> Render
Render --> JS
Render --> GPU
GPU --> Screen
核心思想:
graph LR
Browser --> Isolation[安全隔离能力]
Browser --> Execution[代码执行能力]
Browser --> Rendering[渲染能力]
Browser --> Scheduling[调度能力]
Browser --> Memory[内存管理能力]
| 能力 | 本质 |
|---|---|
| 安全隔离 | 不可信代码的最小权限执行 |
| 渲染流水线 | 状态 → 几何 → 像素 的确定性转换 |
| 调度系统 | 有限主线程上的公平与优先级 |
| 内存管理 | 自动回收 + 停顿控制 |
| 并发抽象 | “看似并行”的单线程语义 |
| 阶段 | 核心问题 | 架构思想 |
|---|---|---|
| 单进程 | 崩溃即全崩 | 简单但脆弱 |
| 多进程 | 隔离与稳定 | 空间换安全 |
| 内部 SOA | 资源浪费 | 服务化、复用 |
| 子系统 | 类型 |
|---|---|
| 执行系统 | JavaScript 引擎(解释 + JIT) |
| 渲染系统 | DOM / CSSOM / Layout / Paint |
| 调度系统 | 事件循环 / 任务队列 |
| 内存系统 | 栈 / 堆 / GC |
| 图形系统 | 图层 / 合成 / GPU |
渲染是一个从“声明式状态”到“像素输出”的确定性流水线。
graph LR
State[HTML/CSS/JS] --> Style[Style]
Style --> Layout[Layout]
Layout --> Paint[Paint]
Paint --> Composite[Composite]
凡是跨越 Layout / Paint 的变更,必然昂贵。
JavaScript 的单线程不是限制,而是:
graph TD
Macro[宏任务队列]
Micro[微任务队列]
Render[渲染阶段]
Macro --> Micro
Micro --> Render
Render --> Macro
| 层级 | 管理策略 |
|---|---|
| 栈 | 确定性、自动回收 |
| 新生代 | 快速分配、复制 |
| 老生代 | 增量标记、并发回收 |
GC 不是消除停顿,而是管理停顿。
虚拟 DOM 是“视图的中间表示(IR)”,而非性能魔法。
其价值不在于快,而在于:
graph LR
State --> VDOM
VDOM --> DOM
DOM --> RenderPipeline
| 边界 | 描述 |
|---|---|
| OS 边界 | 沙箱、权限、进程 |
| GPU 边界 | 图形加速 |
| 网络边界 | 安全协议、同源 |
| 语言边界 | JS / WASM |
浏览器治理的核心目标:
对应机制:
| 治理维度 | 手段 |
|---|---|
| CPU | 调度、分片 |
| 内存 | GC、限制 |
| 时间 | 帧预算(16ms) |
| 权限 | 同源策略 |
是否跨越渲染流水线的边界?
| 场景 | 优先策略 |
|---|---|
| 动画 | 合成属性 |
| 计算 | Worker / WASM |
| 状态更新 | 批量、调度 |
| 跨端 | 中间表示 |
浏览器的真正复杂性不在 API,而在其背后的系统级约束平衡:
理解浏览器,最终不是学习“怎么用”,而是理解:
一个在不可信环境中,构建确定性体验的计算系统,是如何可能的。
这正是浏览器架构长期稳定、不随框架变化而动摇的第一性原理所在。