CellMeasurer with function child({measure})=&gt; <div>)渲染次数过多

时间:2017-12-10 16:57:48

标签: react-virtualized

REF:https://codesandbox.io/s/1vy7ljo877

上的演示

该演示使用2种方法渲染一些图像。

第一行在CellMeasurer中呈现一个元素 而第二行呈现带签名的函数:({measure})=&gt; )

我发现对于函数渲染,在正确计算大小的同时,render方法被调用n ^ 2#次,其中n大约是它试图显示的项目数。

如果启用了deferredMeasurementCache,则问题会成倍增加,因为n会变成集合的大小。

上述结果导致疯狂的长页面加载时间和滚动时的行为非常缓慢。

这是正常行为还是我在CellMeasurer中错误地实现了这个功能?

1 个答案:

答案 0 :(得分:2)

  

如果启用了deferredMeasurementCache,则问题会因为n变为集合的大小而呈指数级变差。

如果您未将CellMeasurerCache传递给Grid作为deferredMeasurementCache道具,则Grid无法保证正常工作。它有必要知道几个案例的缓存。 (也许请查看this part of the docs以确保在用于计算行/列的宽度/高度时,不会误解CellMeasurer应该如何工作。)

话虽如此,你所描述的听起来像就像一个bug,但我不确定它是不是。在较高级别,它是由同步触发forceUpdate()的{​​{3}}引起的(导致所有可见单元格重新渲染)。

起初我认为解决方案可能只是去抖动或排队setState动作。不幸的是,这只会把问题推迟一点;可能性仍然存在。我无法进行太长时间的去抖动,或者我冒险向用户显示明显错误大小的Grid单元格。 (一个太大的去抖可能甚至允许用户继续向前滚动,超过重新渲染。)图像也可能在真实应用程序中远远地(在延迟之后)加载,从而击败我可能做的任何去抖动反正。

这里的问题是,当一个小区报告它有不同的大小时,Grid需要重新布局其他小区(可能会向上或向下移动它们)。在这个简单的例子中,似乎没有必要 - 因为所有图像最终都具有统一的宽度和高度。这不是典型的。由于您已将CellMeasurerCache配置为测量高度,并且由于每列的高度会影响行的高度(因此影响所有其他列,如我在上面链接的文档中所述),{{1}每次报告更改时,必须重新渲染所有单元格。

换句话说,如果您添加了更多行,会将您的示例更改为更像:

Grid

然后可能更容易理解为什么第1行第1列中的单元格的更改可能会影响第1行中所有单元格的高度,以及网格中所有单元格的位置。