共计 2241 个字符,预计需要花费 6 分钟才能阅读完成。
大家好,我卡颂。
可能很多敌人在我的项目中还没用过 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
重度依赖运行时,为了优化性能,并发 是这套架构下的最优倒退方向。