React 18 并发渲染
聊聊 React 18 带来的"后台干活"能力
先说结论:并发渲染让 React 可以同时"后台"计算新 UI,同时保持当前页面可响应。
以前的问题
React 17 及以前,渲染是同步的:
- 开始渲染就必须一直算完
- 中间不能停
- 如果计算量大,页面就卡死
并发怎么工作?
React 18 引入并发,渲染可以被暂停、中止、重启:
- React 可以在后台算新页面的 UI
- 同时当前页面依然可以响应用户操作
- 就像一个人同时处理多个任务(快速切换,而不是一次干完)
新特性
startTransition
把更新标记为"不紧急":
// 紧急:输入框要立即显示
setInputValue(input);
// 非紧急:搜索结果列表渲染(耗时)
startTransition(() => {
setSearchQuery(input);
});
- 用户打字(紧急)会打断列表渲染(非紧急)
- 解决"输入卡顿"问题:先响应输入,等空闲了再渲染列表
useDeferredValue
类似防抖,但更智能:
const deferredQuery = useDeferredValue(query);
- 如果系统繁忙,deferredQuery 会滞后更新
- 用旧值先渲染,避免卡顿
Suspense(流式渲染)
- 配合 SSR,实现流式 HTML
- 页面可以分块发送到浏览器
- 不用等整个页面都准备好才显示
并发 vs 并行
不是多线程! React 依然跑在单线程上。
靠的是:时间切片 + 任务优先级调度。
和 setTimeout 的区别
setTimeout:只是延迟执行,还是会阻塞后续渲染
startTransition:
- 立即开始(在后台跑)
- 如果用户继续输入,可以丢弃没算完的结果,直接算最新的
- setTimeout 做不到
总结
| 特性 | 作用 |
|---|
| 并发 | 可中断渲染 |
| startTransition | 标记非紧急更新 |
| useDeferredValue | 基于性能的延迟 |
| 目标 | 重计算期间 UI 依然响应 |