大家好,我卡颂。
可能很多敌人在我的项目中还没用过Suspense
,然而Suspense
是React
将来倒退十分重要的一环。
本文会解说Suspense
对于React
的意义。
欢送退出人类高质量前端框架群,带飞
React的迭代过程
React
从v16到v18主打的个性经验了三次大的变动:
- v16:Async Mode(异步模式)
- v17:Concurrent Mode(并发模式)
- v18:Concurrent Render(并发更新)
要理解这三次变动的意义,须要先理解React
中一个很容易混同的概念 —— render
(渲染)。
ClassComponent
的render
函数执行时被称为render
:
class App extends Component { render() { // ...这是render函数 }}
而将render
的后果渲染到页面的过程,被称为commit
。
Async Mode
的目标是为了让render
变为异步、可中断的。
Concurrent Mode
的目标是让commit
在用户的感知上是并发的。
因为Concurrent Mode
蕴含breaking change
,所以v18
提出了Concurrent Render
,缩小开发者迁徙的老本。
那么让commit在用户的感知上是并发的是什么意思呢?
“并发”的意义
说到并发,就不得不提Suspense
。思考如下代码:
const App = () => { const [count, setCount] = useState(0); useEffect(() => { setInterval(() => { setCount(count => count + 1); }, 1000); }, []); return ( <> <Suspense fallback={<div>loading...</div>}> <Sub count={count} /> </Suspense> <div>count is {count}</div> </> );};
其中:
- 每过一秒会触发一次更新,将状态
count
更新为count => count + 1
- 在
Sub
中会发动异步申请,申请返回前,包裹Sub
的Suspense
会渲染fallback
假如申请三秒后返回,现实状况下,申请发动前后页面会顺次显示为:
// Sub内申请发动前<div class=“sub”>I am sub, count is 0</div><div>count is 0</div>// Sub内申请发动第1秒<div>loading...</div><div>count is 1</div>// Sub内申请发动第2秒<div>loading...</div><div>count is 2</div>// Sub内申请发动第3秒<div>loading...</div><div>count is 3</div>// Sub内申请胜利后<div class=“sub”>I am sub, request success, count is 4</div><div>count is 4</div>
从用户的视角察看,页面中有两个工作在并发执行:
- 申请
Sub
的工作(察看第一个div
的变动) - 扭转
count
的工作(察看第二个div
的变动)
Suspense
带来的页面中多任务并发执行感觉,就是Concurrent
(并发)在React
中的含意。
其实在Async Mode
时,曾经反对Suspense
。然而下面的代码在Async Mode
的页面中体现如下:
// Sub内申请发动前<div class=“sub”>I am sub, count is 0</div><div>count is 0</div>// Sub内申请发动第1秒<div>loading...</div><div>count is 0</div>// Sub内申请发动第2秒<div>loading...</div><div>count is 0</div>// Sub内申请发动第3秒<div>loading...</div><div>count is 0</div>// Sub内申请胜利后<div class=“sub”>I am sub, request success, count is 4</div><div>count is 4</div>
从用户的视角察看,当申请Sub的工作执行时,扭转count的工作就被解冻了。
这就是为什么被称为Async
(异步)而不是Concurrent
(并发)。
Suspense的意义
能够看到,对于Concurrent
,Suspense
是必不可少的一环。
能够认为,Suspense
的作用是划分页面中须要并发渲染的局部。
比方上例中,通过Suspense
将申请Sub的工作与扭转count的工作划分开,从视觉上并发执行。
当明确了Suspense
的意义后,你会发现,React
接下来在做的事,就是一直裁减Suspense
的场景(也就是说将更多场景纳入并发渲染的领域)。
比方,以后已有的:
React.lazy
- 通过
React
提供的fetch
库革新后的异步申请 useTransition
useDeferredvalue
将来会退出的:
Server Component
Selective Hydration
总结
React
的倒退历程是:从同步到异步,再到并发。
当实现并发后,接下来的倒退方向将是:一直扩大能够应用并发的场景。
Suspense
的作用是划分页面中须要并发渲染的局部。
这套倒退门路从React
诞生伊始就决定了,因为从架构上来说,React
重度依赖运行时,为了优化性能,并发是这套架构下的最优倒退方向。