Concurrent Mode
官方对于 Concurrent Mode
,用了一个有趣的比喻,把 Concurrent Mode
隐喻为版本控制,版本控制大家都了解,平常开发项目时,大家会在同一个项目的不同分支中修改内容,比如修改同一个文件
假设现在没有版本控制,为了避免冲突,A 同学在修改 a 文件时,B、C、D 等其他同学就得等着 A 同学修改完然后释放文件,这种情况下会阻塞 B,C,D 等其他同学的开发进度
而 Concurrent Mode
则提供了一个类似分支的概念,把 A,B,C 等同学比作 React
中的 render
任务,浏览器的渲染进程,IO 进程等等,当React
中的 render
任务执行时,可以不阻塞浏览器中的其他进程
其实严格来说,Concurrent Mode
比作版本控制也不是那么妥当,毕竟场景不是一模一样,只是希望大家能理解到其中的含义即可
个人理解的话,React
中的 Concurrent Mode
是指在 Reconciler
中处理 long task
时,可以不阻塞浏览器中的其他进程,并且 React
中的 render 任务
具有各自的优先级,任务可以通过过时间分片 + 优先级调度的方式在执行和暂停之间切换状态
Legacy & Concurrent & Blocking
React v17
中提供了三种可选的方式来创建 React
应用,分别是 Legacy Mode
,Concurrent Mode
,Blocking Moode
Legacy Mode
是我们熟悉的传统模式,目前是通过 ReactDOM.render
来触发这个模式,Legacy Mode
下大家都熟悉,Reconcile Fiber
流程一步到位,不可中断,当页面中存在大量组件 render
时会导致时间过长,阻塞浏览器的渲染进程,页面响应速度慢,交互卡顿明显
Concurrent Mode
目的是为了能让渲染流程变的可中断,也就是我们现在常听到的 Interruptible Rendering
- 可中断式渲染 这一概念
React
计划在 v18 中正式默认启用 Concurrent Mode
,但是让大型的 React App
一口气升级上来难免会遇到一些问题,主要体现在 React
现在的生态中会有些组件还在使用一些不安全的生命周期,一些老旧的 React Library
可能没办法跟 Concurrent Mode
兼容运行
为了能更加平滑过渡到 Concurrent Mode
,新增了 Blocking Mode
,目前 React
v17 中则是采用了 Blocking Mode
的过渡模式,可以通过 ReactDOM.createBlockingRoot
开启过渡模式,在 Blocking Mode
期间,减少 unsafe_liftcycle
,String Refs
,Legacy Context
,findDOMNode
等不稳定或者不兼容 api 的使用,等待 React
的生态逐步跟进后,再尝试使用 React
v18 的新特性