React如何渲染大数据量的列表?
我们经常会遇到这种需求,根据数据展示列表。这种代码估计你已经撸过成百上千次了。
但如果你需要同时展示成千上万条数据呢,必然会造成浏览器卡顿,丢帧,甚至卡死的问题。
本文将介绍利用react-virtualized来高效渲染大数据量列表。
开始吧!
首先创建一个React 应用
create-react-app virtualization
复制代码 应用将展示1000条如下这样的评论:
我们引入第三方库lorem-ipsum来生成模拟数据:
cd virtualizationnpm install --save lorem-ipsum
复制代码 在 src/App.js 中引入 lorem-ipsum:
import loremIpsum from 'lorem-ipsum';
复制代码 接下来创造一个1000条数据的数组:
const rowCount = 1000;class App extends Component {constructor() {super();this.list = Array(rowCount).fill().map((val, idx) => {return {id: idx, name: 'John Doe',image: 'http://via.placeholder.com/40',text: loremIpsum({count: 1, units: 'sentences',sentenceLowerBound: 4,sentenceUpperBound: 8 })}});}//...
}
复制代码 以上每条数据都包含 id、用户名、图片、随机生成4~8个字评论。
在 render() 中使用这个数组:
render() {return (<div className="App"><header className="App-header"><img src={logo} className="App-logo" alt="logo" /><h1 className="App-title">Welcome to Reacth1>header><div className="list">{this.list.map(this.renderRow.bind(this))}div>div>);
}
复制代码 增加 renderRow() 来创造列:
renderRow(item) {return (<div key={item.id} className="row"><div className="image"><img src={item.image} alt="" />div><div className="content"><div>{item.name}div><div>{item.text}div>div>div>);
}
复制代码 在 src/App.css 中加点样式:
.list {padding: 10px;
}.row { border-bottom: 1px solid #ebeced;text-align: left;margin: 5px 0;display: flex;align-items: center;
}.image {margin-right: 10px;
}.content {padding: 10px;
}
复制代码 好了,启动项目 yarn start,可以看到如下画面:
查看元素,我们可以看到 DOM 上挂载了非常多的 div:
我们来测测性能
如果你用的是 Chrome,只需几步,快速测试性能:
- 打开开发者工具
- 按Command+Shift+P (Mac) or Control+Shift+P (Windows, Linux) 来打开命令菜单
- 输入
render,下拉框中选择Show Rendering。 - 点击
render页签,FPS Meter前打钩。 - 滚动列表
我们可以看到,当滚动条滚动的时候,帧率从60掉到了38左右。这还是只有1000条数据情况,如果再增大数据,浏览器会出现卡顿,甚至卡死。
接着我们来看看react-virtualized是如何提高性能的?
react-virtualized原理
核心原理:只渲染你所见的。
上面的应用渲染了1000条评论,但屏幕只为你展示了10来条数据,那另外990条的渲染就是浪费的。
如果我们只渲染可见的评论,当鼠标滚动查看更多的时候,将新的节点替换旧的节点。这样就完美解决了性能瓶颈的问题。
怎么用呢?
首先在 src/App.js 中,引入 List 组件:
import { List } from "react-virtualized";
复制代码 替换 render() 原有代码:
{this.list.map(this.renderRow.bind(this))}
复制代码 使用 List 组件
const listHeight = 600;const rowHeight = 50;const rowWidth = 800;//..."list"><Listwidth={rowWidth}height={listHeight}rowHeight={rowHeight}rowRenderer={this.renderRow.bind(this)}rowCount={this.list.length} />div>
复制代码 改写 renderRow():
renderRow({ index, key, style }) {return (<div key={key} style={style} className="row"><div className="image"><img src={this.list[index].image} alt="" />div><div className="content"><div>{this.list[index].name}div><div>{this.list[index].text}div>div>div>);
}
复制代码 启动应用 yarn start:
查看元素:
可以看到只渲染了可见的元素。
性能怎么样呢?
用上面相同的方法测试:
可以看到基本维持在60帧左右。性能杠杠的(^_^)
以上只是对react-virtualized的简单应用,感兴趣可以去试试!
感谢阅读!
作者:缪宇
链接:https://juejin.im/post/5b3ddd11e51d4518f140ef33
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
