fetch on render
: 目前一般数据获取写在 componentDidMount 阶段, 其获取数据的过程中, 执行顺序如下所示:wait Time1
...wait Time2
...这么做存在的问题: 在 B 组件中开始请求数据时至少要等上 Time1
时间, 是一种 network waterfall
而非并发请求
;
fetch then render
: 调用 setState 之前先获取数据
, 比如在 A 组件的 componentDidMount 中使用 Promise.all()
同时执行 fetchA, fetchB
render
这么做存在的问题: A 组件和 B 组件上的数据显示时间取决于请求时间更长的接口, 所以页面上渲染数据必然会存在延时
;
render as fetch
: 使用 Suspense 后的效果呢?render
它很好地规避了上述遇到的两个问题:
不能并发请求接口
的痛点;页面数据内容存在延时
的问题;Default Mode
: Receded → Skeleton → CompletePreferred Mode
: Pending → Skeleton → Complete总结:
useTransition
进入 Pending 状态 —— 位于当前页的同时, 加载下一页(想象多元宇宙)useDeferredValue
的作用: 能让组件中的部分内容延迟加载
。
const deferredText = useDeferredValue(text, {timeoutMs: 5000})
这里第二个参数表示, 能确保 5s 之内输入框内的输入是顺滑的。
SuspenseList 中的 revealOrder
字段能控制其里面 Suspense 节点的输出顺序, tail
字段控制当前加载的节点数。
function ProfilePage({ resource }) {return (<SuspenseList revealOrder="forwards" tail="collapsed"><ProfileDetails resource={resource} /><Suspense fallback={<h2>Loading posts...</h2>}><ProfileTimeline resource={resource} /></Suspense><Suspense fallback={<h2>Loading fun facts...</h2>}><ProfileTrivia resource={resource} /></Suspense></SuspenseList>);}