react大块数据的非阻塞渲染

IT技术 javascript performance reactjs
2021-05-18 13:46:31

最近开始学习react,想知道大数据的非阻塞UI线程渲染有没有什么模式。比方说,我们拿这个例子:,点击创建很多项目,设置数量,假设为 10000,我们将冻结 UI 近 10 秒。它使用 observables 平滑更新,一旦完成渲染,我明白了,但是有没有办法以块的形式平滑地渲染它?

通常,您设置某种数组,将其切片,假设为 50,处理这些并将 setTimeout 设置为 0 以切片另外 50,依此类推。重复直到数组的长度为 0。是否有用于执行此操作的react组件的模式?也许一些插件或直到mixin?

4个回答

您可以使用requestIdleCallback来延迟渲染:

function DeferredRender({ children, idleTimeout }) {
  const [render, setRender] = React.useState(false);

  React.useEffect(() => {
    if (render) setRender(false);
    const id = requestIdleCallback(() => setRender(true), { timeout: idleTimeout });

    return () => cancelIdleCallback(id);
  }, [idleTimeout]);

  if (!render) return null;

  return children;
}
<DeferredRender idleTimeout={1000}>
 <ExpensiveStuff />
</DeferredRender>

React并发模式正在解决 UI 停顿问题。您可以观看一些演讲[1] [2]以了解如何操作。这不会让您的 UI 神奇地更新得更快,它只会帮助您在 UI 更新时使 UI 不会冻结。

您的两个选择是:

  1. 正如您所说,以块为单位更新状态。如果您将工作分块,则不能只根据时间进行:您无法根据时间对最佳值进行硬编码,因为人们的计算机性能不同。相反,要么使用浏览器 API,requestIdleCallback要么查看调度程序 NPM 库(https://philippspiess.com/scheduling-in-react/),以便尽可能积极地完成工作,但以不会导致浏览器挂起。
  2. 或者使用图书馆来创建一个虚拟列表,因为另一个人已经回答了。

对于类似的问题,我将数据分块,然后使用reduce和 Promise序列化处理

chunks.reduce( (previousPromise, nextChunk) => {
  return previousPromise.then(processChunkAndUpdateComponentStateAsPromise(nextChunk));
}, Promise.resolve());

对于多达 10,000 个项目的列表,我建议使用虚拟化列表。React 的一个流行实现是 react-virtualized:http : //bvaughn.github.io/react-virtualized/#/components/List

这样做的原因是虚拟化列表只会呈现可见的内容,因此即使您有大量数据要显示,它也会很快。您也可以将初始渲染分成批次,但如果这样做,您可能会遇到其他性能问题(由于 DOM 过多、可观察对象过多等)。