3

我有一个react-virtualized 的无限滚动列表,(大部分设置都是从​​这个例子复制而来的)。我正在为它提供规范rowRenderer所需的功能。如果该函数非常轻量级(即返回一个非常基本的组件作为行),则此方法可以正常工作。但我的渲染包括一些超过一些属性。这应该不会导致任何问题,除非函数在滚动时被调用数十次甚至数百次。这会导致性能问题,使滚动不够平滑。到目前为止,我尝试过:rowRendererRowComponentArray.maprowRenderer

  1. 缓存我的rowRenderer这个工作,但我不喜欢这个解决方案,因为它可能会在未来引起问题。
  2. 使我RowComponent的渲染函数纯净并shouldComponentUpdate使用react-addons-shallow-compare. 这略微提高了性能,但还不够。

这个例子中,这个rowRenderer函数在每次滚动时也被调用了很多次(没有性能问题,因为这个函数非常轻量级),这让我相信这种行为是设计使然。所以:
缓存是一个好的解决方案吗?关于如何将它与我的应用程序状态同步的任何建议(我使用 redux 进行状态管理)?我在文档中遗漏了什么可以减少调用rowRenderer(滚动时我的行没有理由改变)?

4

2 回答 2

4

react-virtualized 的作者在这里。

您的rowRenderer方法应该是轻量级的,因为正如您所发现的,当用户滚动时它们可能会被快速调用。好消息是——因为浏览器在一个独立于 UI 的线程中管理滚动,这通常不会导致任何性能问题。如果有的话,您可能会在滚动方向上注意到列表边缘的一些空白/空白区域 - 表明您的渲染器无法跟上用户的滚动速度。

但需要注意的一个警告是,如果将触摸或滚轮事件处理程序附加到反应虚拟化组件或其 DOM 祖先之一,这将强制浏览器在主/UI 线程中滚动。这肯定会导致缓慢。

我目前正在进行重大更新(版本 7 ),其中包括将命名参数传递给用户函数,例如. 这将使我能够传递元信息(例如列表当前是否正在滚动),这可以让您在滚动进行时推迟“繁重”的逻辑。不幸的是,除非您愿意像 doron-zavelevsky 提到的那样使用超时,否则在版本 6 中这是不可能的。rowRenderer

编辑:您可能会很高兴地了解到,通过此提交单元缓存已进入即将发布的第 7 版。

于 2016-05-05T15:42:11.980 回答
3

根据我对这个库的经验(虽然我没有使用最新版本) - 这是设计使然。这是有道理的——为了避免一次渲染所有列表——并允许你无限滚动——它每次都要求你渲染当前查看的项目。您的目标是优化渲染功能 - 正如您自己提到的那样。可以改善您的整体体验的另一件事是检查并查看您的项目是否在其 componentDidMount 生命周期方法中包含一些复杂的代码 - 或任何其他运行后渲染的代码。如果是这种情况 - 您可以通过超时延迟这些计算来优化快速滚动 - 并且只有在超时过去时组件仍然安装时才让它们运行。

考虑一下您快速滚动项目以到达底部的情况 - 完全填充您滚动过去的所有项目是没有意义的。因此,您尽可能快地返回渲染结果 - 在项目内等待约 200 毫秒 - 然后检查组件是否仍然安装并执行实际工作。

由于 isMounted 已过时,您只需在 componentDidMount 期间将变量设置为 true,然后将 componentWillUnmount 设置回 false。

于 2016-05-05T12:09:36.503 回答