原理

虚拟列表是一种根据滚动容器元素的可视区域来渲染长列表数据中某一个部分数据的技术。

实现

  1. 获取容器高度 clientHeight
  2. 获取列表项元素高度 offsetHeight
  3. 计算可视区域可渲染个数 count = clientHeight / offsetHeight
  4. 获取可视区域渲染数据的 start 和 end
  5. 根据 start 和 end 截断长列表 sliceList = dataList.slice(start, end)
  6. 渲染 sliceList

    react-virtualized

    很多库的 API 设计都是由原理实现决定的,所有 react-virtualized 需要传入很多上面提及的数据参数。

    main components

  • Grid. It renders tabular data along the vertical and horizontal axes.
  • List. It renders a list of elements using a Grid component internally.
  • Table. It renders a table with a fixed header and vertically scrollable body content. It also uses a Grid component internally.
  • Masonry. It renders dynamically-sized, user-positioned cells with vertical scrolling support.
  • Collection. It renders arbitrarily positioned and overlapping data.

    List

    ```javascript rowRenderer = ({ index, isScrolling, key, style }) => { return (
    1. <div key={key} style={style}>
    2. <div>{this.props.data[index].username}</div>
    3. <div>{this.props.data[index].email}</div>
    4. </div>
    ); };

```

  • rowCount: This takes the numbers of a row in a list that we pass to calculate the length of our list.
  • width: The width of the list.
  • height: The height of the list.
  • rowHeight: This can be a number or a function that returns a row height given its index.
  • rowRenderer: This is responsible for rendering the row. the list is not supposed to be passed directly, so we pass the rowRenderer function that we created in this tutorial.
  • overscanRowCount: This is used to render additional rows in the direction the user scrolls. It reduces the chances of the user scrolling faster than the virtualized content is rendered.

    rowRenderer

  • index: The numeric ID of a record.

  • isScrolling: Indicates if the scrolling is occurring in the List component.
  • isVisible: Determines if a row is visible or out of view.
  • key: The records position in the array.
  • parent: Defines whether the list is a parent or a child of another list.
  • style: A style object to position the row.

    CellMeasurer

    解决子元素动态变化问题

参考资料

  1. 浅说虚拟列表的实现原理 #70
  2. 剖析无限滚动虚拟列表的实现原理
  3. Rendering large lists with React Virtualized
  4. Rendering Lists Using React Virtualized