第1节:浏览器的多进程架构

0 阅读3分钟

题记:理解 React 为什么这样设计,要先从它运行的土壤说起。


🔍 本节要点

  • 现代浏览器不止一个进程
  • 渲染进程是 React 的"主战场"
  • 多进程如何影响 React 的渲染策略

浏览器不只是"一个程序"

很多人写 JavaScript 的时候,默认浏览器是一个黑盒。但实际上,从 Chrome 57 开始,Chromium 内核就已经采用了多进程架构——这直接塑造了 React 后来所有设计的底层约束。

当我们打开一个标签页,浏览器会启动一套复杂的进程模型:

进程职责
Browser 进程地址栏、书签、前进后退、网络请求、下载管理
Renderer 渲染进程每个标签页一个,包含主线程、合成线程、光栅化线程
GPU 进程跨标签页的 GPU 任务,比如 CSS 动画、Canvas
Network 网络进程独立处理 HTTP 请求,不阻塞 UI
Plugin 插件进程第三方插件隔离运行

关键在于:每个标签页默认拥有独立的渲染进程。这意味着一个页面崩溃不会波及其他页面。

渲染进程内部:React 的"主战场"

渲染进程是 React 开发者的核心战场。它内部包含多个线程:

  • 主线程(Main Thread):JavaScript 执行、DOM 操作、事件分发。这是 React 的 workLoop 奔跑的地方。
  • 合成线程(Compositor Thread):负责将图层合成并推送到屏幕。滚动和 CSS transform 动画可以在不经过主线程的情况下运行。
  • 光栅化线程(Raster Thread):将绘制指令转化为像素。

React 的渲染是同步且在主线程上的。这意味着当 React 正在 reconcile(调和)虚拟 DOM 时,用户的点击事件、输入、动画都必须等待——除非 React 主动让出主线程。

为什么这影响了 React 的设计?

当你理解了这个架构,很多 React 的"奇怪设计"就有了答案:

为什么 React 18 引入 Concurrent Rendering? 因为主线程被 JavaScript 霸占时,用户的滚动、点击都是无响应的。React 需要一种机制,把大块的渲染工作切成小片,每片之间让浏览器喘口气。

为什么 requestIdleCallback 被 React Scheduler 重新实现? 因为浏览器原生的 requestIdleCallback API 在 Safari 上根本不存在,而且调度精度不够。React 必须自己造轮子。

为什么 useTransition 和 useDeferredValue 能"异步化"状态更新? 它们本质上是在告诉 React:"这个更新不急,可以在浏览器空闲时慢慢来,不要卡住用户的输入。"

一张图理解进程与线程

┌─────────────────────────────────────────┐
│              Browser 进程                 │
│  (统筹协调,不参与页面内容渲染)            │
└────────────────┬────────────────────────┘
                 │ 每个标签页独立运行
┌────────────────▼────────────────────────┐
│           Renderer 渲染进程               │
│                                         │
│  ┌─────────────────────────────────┐     │
│  │     主线程 Main Thread          │     │
│  │  JS执行 / React workLoop        │     │
│  │  DOM更新 / 事件处理              │     │
│  └─────────────┬───────────────────┘     │
│                │                        │
│  ┌─────────────▼───────────────────┐     │
│  │     合成线程 Compositor         │     │
│  │  图层合成 / 推送帧到屏幕          │     │
│  └─────────────────────────────────┘     │
└─────────────────────────────────────────┘

本节小结

浏览器的多进程架构是 React 所有底层设计的起点。主线程只有一个,而 React 要在上面完成协调、计算、布局、绘制——这些需求之间的张力,催生了 Fiber、Scheduler、Concurrent Mode 这一整套体系。

理解了这个,你就理解了一个核心矛盾:React 想做的事,永远比它能用的时间多。

2_1080468923_184_97_3_1098378589_66a27b56910902a8e766d2b25dd3b2db.png