【问题标题】:react-virtualized - opt in or out of virtualizationreact-virtualized - 选择加入或退出虚拟化
【发布时间】:2018-04-02 08:11:41
【问题描述】:

我在我正在开发的类似日历的应用程序中使用最大胆的react-virtualized 组件。

我使用三个带有ScrollSync 的网格,就像在this example 中一样,但也使用cellRangeRenderer 在网格顶部呈现“药丸”。

该应用程序运行良好,但是我发现在速度较慢的计算机上,滚动时的渲染速度可能会非常慢(大约 40 列乘 20 行,单个视图中最多可以渲染 40 个左右的药丸)

将使用此应用程序的一些人实际上并不真正需要虚拟化,因为整个数据表 并不大。所以,我想做的是继续使用react-virtualized 提供的通用框架,但对于行 x 的用户,网格将正常虚拟化。

我知道cellRangeRenderer 只接收行和列的开始和结束索引,然后为网格的每个单元格返回一个 div 数组,所以我可以想象只发送整个网格的开始和结束索引然后将返回整个网格。我只是不确定如何覆盖滚动时的重新渲染。

我很想听听任何建议或类似的经历。

【问题讨论】:

    标签: javascript performance reactjs react-virtualized


    【解决方案1】:

    当您的行数小到不需要虚拟化时,我建议不要使用react-virtualized 组件。它不必要地增加了复杂性等。 :)

    您可以创建一个假的 Grid 组件,它只呈现所有行,然后根据行数有条件地在它和真实的组件之间进行交换,例如:

    import {Grid} from 'react-virtualized';
    import FakeGrid from './FakeGrid';
    
    // Your render function
    const GridComponent = this.props.rowCount > SOME_THRESHOLD
      ? Grid
      : FakeGrid
    
    return <GridComponent {...gridProps} />
    

    【讨论】:

    • 感谢@brianvaughn,我将对此进行试验。我想尽可能多地利用react-virtualized 的优点(特别是cellRangeRendererscrollSync 函数),所以我会尝试一下您的建议,看看效果如何。会让你知道。一如既往,感谢您在这个项目中的积极性:-)
    • 因为我开发的大部分逻辑和功能都包含在 react-virtualized 组件中,如果有一种方法可以只渲染整个网格一次但拦截任何对重新渲染。我试过查看Grid 的源代码,但看不到如何实现这一点。你有什么建议吗?
    • 我想你可以通过给 RV 一个特定的宽度 + 高度 + 行/列数来强制它最初呈现特定数量的行+列,然后在 componentDidMount 中设置一个状态来伪造这个告诉渲染“现在正常运行,您正在浏览器中运行”的标志。
    • 谢谢布赖恩。我最终只是把它留给了所有情况下的虚拟化。我最终确实设法破解了使用您提出的方法渲染整个网格的解决方案,但是渲染时间非常慢。干杯。
    【解决方案2】:

    我有一个组件,它包装了来自react-virtualizedTable,我将一个fixedHeight 道具(boolean)传递给它,并按如下方式使用它:

    import {
      AutoSizer,
      Table as VirtualizedTable
    } from 'react-virtualized';
    
    const Table = (props) => {
      const getHeight = (autoSizerHeight) => {
        const { fixedHeight, headerHeight, rowHeight, rowCount } = props;
    
        // I'm checking for `rowCount` in order to properly render the `noRowsRenderer` component
        return fixedHeight && rowCount
          ? headerHeight + rowHeight * rowCount
          : autoSizerHeight;
      }
      
      return (
        <AutoSizer
          disableHeight={props.fixedHeight && Boolean(rowCount)}>
          {({ height, width }) => (
            <VirtualizedTable
              ...
              width={width}
              height={getHeight(height)}>
              {props.columnDefs.map(
                (columnDef, columnIndex) => (
                  <Column ... />
                )
              )}
            </VirtualizedTable>
          )}
        </AutoSizer>
      );
    }

    注意:

    我没有选择退出虚拟化,当我不想在表格内滚动时,或者当数据分页并且页面不是很大时,我通常使用 fixedHeight 属性。

    希望对你有帮助:)

    【讨论】:

    • 感谢您的解决方案。我去看看:-)
    猜你喜欢
    • 1970-01-01
    • 2021-02-03
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多