在展示大型列表和表格数据, 如: 城市列表、通讯录、微博等,会导致页面不流畅、卡顿等性能问题。
原因: 大量的DOM节点的重绘和重排,设备老旧;导致移动设备耗电耗电加快,设备发热。
优化方案: 1.懒渲染 2. react-virtualized (可视区域渲染)
懒渲染: 每次只渲染一部分数据,加载更多时再渲染一部分数据;
优点: 每次渲染一部分数据,数据块
缺点: 等数据量加载到非常多时,页面依然存在大量DOM节点,占用内存过多、降低浏览器性能;
react-virtualized: 可视区域渲染
github: https://github.com/bvaughn/react-virtualized
install: npm install react-virtualized
列表组件文档: https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md
import React, { Component } from 'react'
import 'react-virtualized/styles.css' //导入样式
import {List} from 'react-virtualized'; //导入list组件
// List data as an array of strings
const list = Array(100).fill('mmmm')
function rowRenderer({
key, // 唯一值
index, // 索引号
isScrolling, // 是否在滚动中
isVisible, // 当前行在list中是否可见
style, // 每行的样式对象
}){
return (
<div key={key} style={style}>
{index} --- {list[index]} {isScrolling+''}
</div>
);
}
export default class index extends Component {
render() {
return (
<div>
<List width={300} height={300} rowCount={list.length} rowHeight={20} rowRenderer={rowRenderer}/>,
</div>
)
}
}
接下来需要导入AutoSizer组件让list组件占满屏幕
AutoSizer组件是通过render-props模式暴露width和height属性,将暴露的width&height设置给list组件,设置页面的根元素高度100%,让list占满页面。再减去导航栏的高度,让页面不要出现全局滚动条,避免顶部导航栏滚动。
AutoSizer组件文档: https://github.com/bvaughn/react-virtualized/blob/master/docs/AutoSizer.md
import React, { Component } from 'react'
import 'react-virtualized/styles.css' //导入样式
import {List, AutoSizer} from 'react-virtualized'; //导入list组件
import './index.css'
export default class index extends Component {
state = {
list: Array(100).fill('mmmm'),
}
rowRenderer = ({key, index, isScrolling, isVisible, style,})=>{
return this.state.list.map((item,index)=>{
return (
<div key={index} style={style}>
<div className="item-name">{item}</div>
</div>
)
})
}
render() {
return (
<div className="city-list">
<div className="nav-bar">title</div>
<AutoSizer>
{({height, width}) => (
<List
height={height}
rowCount={this.state.list.length}
rowHeight={ 50} //高度是item-name的css高度
rowRenderer={this.rowRenderer}
width={width}
/>
)}
</AutoSizer>
</div>
)
}
}
.city-list{
/* 减去nav-bar的高度 */
height: calc(100% - 45px)
}
#root,.App{
width: 100%;
height: 100%;
}
.nav-bar{
width: 100%;
height: 45px;
line-height: 45px;
background: orange;
color: #fff;
text-align: center;
}
.item-name{
width: 100%;
height: 50px;
line-height: 50px;
padding: 0 15px;
border-bottom: 1px solid #eee;
font-size: 16px;
color: #333;
background: #fff;
cursor: pointer;
}
网友评论