在 React 内部,每一次渲染任务都会给不同的更新分配一个“优先级”。
React 17 开始,Fiber 架构中引入了Lanes 模型(车道模型)——就像高速公路一样,不同类型的更新在不同车道上并行行驶,例如用户输入、网络请求、动画渲染等。
但到了 React 18,这条“高速公路”正式通车进入并发模式🚦。
🧩 1. Lanes 是什么鬼?
简单地说,Lanes 是比 ExpirationTime 更灵活的任务优先级系统。
| 比喻 | 技术解释 |
|---|---|
| 🚗 每辆车是一条状态更新(setState) | Fiber 节点更新任务 |
| 🛣 每条车道是一个优先级(Lane) | 不同任务的调度优先级 |
| 🚧 交通规则是调度器(Scheduler) | React Scheduler 控制何时执行哪个 Lane |
👉 React 会把不同类型的更新放进不同的 Lane,
再根据优先级(priority)合并或分裂执行,达到灵活调度的目的。
⚙️ 2. React 17:有 Lanes,但没“通车” 🚧
在 React 17 中,Lanes 已经实现,但几乎全都在幕后运行。
之所以引入它,是为了后续的并发特性(Concurrent Features)铺路。
React 17 的 Lane 更像是准备好的立交桥,但所有车还是走同一条慢车道。
React 17 的更新依然是同步阻塞式调和:
当有一个组件要重新渲染时,React 不会停下来问“要不要暂停一下”,而是直接一路冲到底。
setState(value); // React 17: 同步、直接阻塞主线程这意味着:
- 高优先级任务(用户输入)不能中断低优先级任务;
- 慢组件会拖垮整次更新;
- “时间切片 (Time Slicing)” 概念还没真正启用。
⚡ 3. React 18:Lanes 真正开跑!并发启用 🚀
React 18 引入了并发渲染(Concurrent Rendering),
这让 Lanes 的作用正式显现:
“不同优先级的任务在不同车道上行驶,可以随时切换、暂停或恢复。”
🧠 核心机制
React 18 会根据更新类型分配不同的 Lane:
| 更新类型 | Lane Priority | 示例 |
|---|---|---|
| 🕹 用户交互(点击、输入) | SyncLane(最高) | onClick,onChange |
| ⏱ 过渡更新(Transition) | TransitionLanes | startTransition(() => setState(...)) |
| 💤 异步渲染(数据请求) | DefaultLanes / Suspense | 加载数据的组件 |
| 🌙 空闲任务 | IdleLane | 后台预取 |
🧵 React 18 的执行流程:
- 用户调用一次
setState - React 分配一个 Lane(比如 “TransitionLane”)
- Scheduler 检查是否有更高优先级的更新在进行
- 如果有,暂停当前渲染(即“打断”)
- 等空闲时间再恢复渲染
这样,你在界面中快速输入时,不会被慢数据渲染卡顿所阻塞。
比如 👇
import { startTransition, useState } from "react"; function SearchApp() { const [query, setQuery] = useState(''); const [results, setResults] = useState([]); function handleInput(e) { const q = e.target.value; setQuery(q); // 👇 将结果更新标记为“过渡任务” startTransition(() => { setResults(expensiveSearch(q)); // 假设很耗时 }); } return ( <input value={query} onChange={handleInput} placeholder="输入以搜索..." /> ); }🧩结果:
- 输入框更新(高优先级)🚗💨 在 FAST LANE。
- 搜索结果渲染(低优先级)🚙 在 SLOW LANE。
- 用户体验——顺滑如丝🎐。
🔮 4. 同步 vs 并发:线程没变,调度变了
🧵并发渲染 ≠ 多线程
React 依然运行在单个 JS 线程,但通过分片调度 (time slicing)实现任务“让出时间”:
while (hasNextUnitOfWork && timeRemaining() > 1) { performUnitOfWork(nextUnitOfWork); }每个 Fiber 更新称为一个 “Unit of Work”,
React 在执行过程中会不断检查是否该“让路”:
- 浏览器要绘制?➡️ 暂停;
- 用户有输入事件?➡️ 立即响应;
- 主线程空闲?➡️ 继续渲染。
这种行为就像《疯狂动物城》里的闪电树懒 🦥 突然喝了几杯红牛——依旧顺序执行,但“懂得让路”。
🧮 5. React 17 vs 18 Lane 调度差异图
| 对比项 | React 17 | React 18 |
|---|---|---|
| Lane 系统 | 内部存在但未全面启用 | 全量启用 |
| 并发渲染 | ❌ 同步阻塞 | ✅ 支持中断 / 恢复 |
| Transition API | ❌ 无 | ✅ startTransition 等 |
| Scheduler 优先级 | 静态分配 | 动态分配,多级优先 |
| 更新协调 | 单通道更新 | 多车道分流更新 |
💬 6. 小结(带点哲学 🧘)
React 17 的 Fiber 是“多核 CPU”,但只开了一个核。
React 18 则是真正启用多调度通道的阶段。
换句话说,
“React 17 是火车:一列车厢接着一列;
React 18 是地铁:多条线路、分时发车、各行其道。”
🎯 结语:Lanes 是 React 哲学的具象化
React 一直追求的,不只是「更新界面快」,
而是「保证交互始终流畅」。
Lanes 让这种理念成为可能。
它让开发者像交通调度员一样,精确控制 UI 的优先级流量。
🚦 React 17:红灯。
🚀 React 18:绿灯亮起,全速前进。
原文: https://juejin.cn/post/75847303