我有一个react-virtualized's无限滚动列表,(大多数设置是从this example复制的)。我正在为其提供rowRenderer
函数,例如specs要求。如果rowRenderer
函数非常轻量级(即返回一个非常基本的组件作为行),这可以正常工作。
但是我的RowComponent
的呈现在某些属性上包含了一些Array.map
。这不应该导致任何问题,除了在滚动时rowRenderer
函数被称为 tens 或甚至数百次。这会导致性能问题,使滚动不够平滑。
到目前为止我试过了:
rowRenderer
这有效,但我不喜欢这个解决方案,因为它可能在将来引起问题。RowComponent
的渲染功能纯净,并使用shouldComponentUpdate
实施react-addons-shallow-compare
。这略微改善了性能但还不够。在this example中,每个滚动也会多次调用rowRenderer
函数(由于函数非常轻量,因此没有执行问题),这让我相信这种行为是设计的。所以:
缓存是一个很好的解决方案吗?有关如何将其与我的应用程序状态同步的任何建议(我使用redux进行状态管理)?我在文档中遗漏了哪些内容可以减少对rowRenderer
的调用(滚动时我的行没有变化的原因)?
答案 0 :(得分:4)
这里反应虚拟化的作者。
您的awk -F, '{delete a; for (i=1;i<=NF;i++) if ($i!="") if ($i in a) {print; next} else a[$i]}' file
John,Smith,Smith,21
John,42,42,42
方法应该是轻量级的,因为正如您所发现的,当用户滚动时,它们可能会被快速调用。好消息是,由于浏览器在UI的单独线程中管理滚动,因此通常不会导致任何性能问题。如果有的话,您可能会在列表边缘看到一些空白/空白区域,表示您的渲染器无法跟上用户的滚动速度。
需要注意的一点是,如果将touch或wheel事件处理程序附加到react-virtualized组件或其DOM祖先之一,这将强制浏览器在main / UI线程中滚动。这肯定会导致缓慢。
我目前正在in the middle进行重大更新(version 7),除其他外,它会将命名参数传递给用户函数,例如rowRenderer
。这将使我能够传递元信息(例如列表当前是否正在滚动),这可以使您能够推迟&#34; heavy&#34;滚动正在进行中的逻辑。不幸的是,在版本6中这是不可能的,除非你愿意像doron-zavelevsky所提到的那样使用超时。
修改:您可能会很高兴地了解到this commit细胞缓存已进入即将发布的第7版。
答案 1 :(得分:3)
根据我对这个库的经验(虽然我没有使用最新版本) - 这是设计的。 这是有道理的 - 为了避免一次渲染所有列表 - 并允许无限滚动 - 它每次都会要求您渲染当前查看的项目。 您的目标是优化渲染功能 - 正如您自己提到的那样。 可以改善整体体验的另一件事是检查并查看您的项目是否包含其componentDidMount生命周期方法中的一些复杂代码 - 或者任何其他运行后渲染的代码。如果是这种情况 - 您可以通过延迟延迟这些计算来优化快速滚动 - 并且只有在超时通过时组件仍然挂载时才让它们运行。
考虑一下你快速滚动项目到底部的情况 - 完全填充你在那里滚动过去的所有项目是没有意义的。因此,您尽可能快地返回渲染结果 - 并在项目内等待〜200ms - 然后检查组件是否仍然安装并执行实际工作。
由于isMounted已过时,您可以在componentDidMount期间将变量设置为true,然后将componentWillUnmount设置为false。