前言:
当一个页面中需要接受接口返回的全部数据进行页面渲染时间,如果数据量比较庞大,前端在渲染dom的过程中需要花费时间,造成页面经常出现卡顿现象。
需求:通过虚拟加载,优化页面渲染速度
优点:不需要固定行元素高度一致
行元素等高的虚拟列表实现方法
实现方法
npm 安装 react-virtualized
npm install react-virtualized --save
页面引入
import { List as VirtualizedList, AutoSizer, CellMeasurer, CellMeasurerCache } from 'react-virtualized';
Cp.jsx
import React, { Component } from 'react';
import { List as VirtualizedList, AutoSizer, CellMeasurer, CellMeasurerCache } from 'react-virtualized';
class Cp extends Component {
constructor(props) {
super(props);
this.cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 100 // 未计算的单元格初始默认的高度
});
this.state = {
viewWidth: 200,
viewHeight: 500,
dataList: [
{id: 1, content1: '小灰灰学编程小灰灰学编程小灰灰学编程', content2: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程'},
{id: 2, content1: '小灰灰学编程', content2: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程'},
{id: 3, content1: '小灰灰学编程小灰灰学编程', content2: ''},
{id: 4, content1: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程', content2: '小灰灰学编程'},
{id: 5, content1: '小灰灰学编程', content2: ''},
{id: 6, content1: '小灰灰学编程小灰灰学编程', content2: '小灰灰学编程'},
{id: 7, content1: '小灰灰学编程小灰灰学编程小灰灰学编程', content2: '小灰灰学编程'},
{id: 8, content1: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程', content2: '小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程小灰灰学编程'},
{id: 9, content1: '小灰灰学编程小灰灰学编程', content2: ''},
{id: 10, content1: '小灰灰学编程', content2: '小灰灰学编程'},
{id: 7, content1: '小灰灰学编程', content2: '小灰灰学编程小小灰灰学编程小灰灰学编程小灰灰学编程灰小灰灰学编程灰学编程'},
{id: 8, content1: '小灰灰学编程', content2: '小灰灰学编程小小灰灰学编程灰灰学编程'},
{id: 9, content1: '小灰灰学编程小灰灰学编程', content2: ''},
{id: 10, content1: '小灰灰学编程', content2: '小灰灰学编程'},
]
}
}
componentDidUpdate() {
// 重置所有单元格的计算缓存
this.cache.clearAll();
}
/**
* rowRenderer 渲染行元素的方法
* index: 索引
* key: 记录在数组中的位置
* parent: 定义该列表是另一个列表的父列表还是子列表
* style: 用于定位行的样式对象
* isVisible: 确定行是否可见或不可见
* isScrolling: 指示组件中是否发生滚动 List
*
* CellMeasurer 自动计算单元格内容的高阶组件
* cache: 在CellMeasure和他们父级的Grid之间共享的缓存
* children: 子元素 可以是一个react元素或者函数
* columnIndex: 经计算的列index | 0
* parent: 父级Grid的引用
* rowIndex: 经计算的行index
*/
rowRenderer = ({ index, key, parent, style }) =>{
const {dataList} = this.state
const itemData = dataList[index];
return (
<div key={key} style={style}>
<CellMeasurer
cache={this.cache}
columnIndex={0}
key={key}
rowIndex={index}
parent={parent}
>
<div>
<div>{`第${itemData.id}个元素`}</div>
<div>content1: {itemData.content1}</div>
<div>{itemData.content2}</div>
</div>
</CellMeasurer>
</div>
);
}
render() {
const {dataList} = this.state
return (
<div className="virtualized-list">
<AutoSizer>
{({ viewWidth, viewHeight }) => (
/**
* VirtualizedList
* width: 可视区域宽度
* height: 可视区域高度
* rowHeight: 行高度
* rowCount: 列表长度
* dataList: 列表数据
* rowRenderer: 渲染行元素的方法
* overscanRowCount: 用于沿用户滚动的方向呈现附加行
* deferredMeasurementCache: 用于临时呈现数据,缓存计算数据
*/
<VirtualizedList
width={this.state.viewWidth}
height={this.state.viewHeight}
rowHeight={this.cache.rowHeight}
rowCount={dataList.length}
rowRenderer={this.rowRenderer}
deferredMeasurementCache={this.cache}
dataList={dataList}
overscanRowCount={1}
/>
)}
</AutoSizer>
</div>
);
}
}
export default Cp;