React 18 并发渲染

聊聊 React 18 带来的"后台干活"能力

先说结论:并发渲染让 React 可以同时"后台"计算新 UI,同时保持当前页面可响应。

以前的问题

React 17 及以前,渲染是同步的:

  1. 开始渲染就必须一直算完
  2. 中间不能停
  3. 如果计算量大,页面就卡死

并发怎么工作?

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 依然响应