長列表性能優化
概述
在展示大型列表和表格數據的時候(城市列表、通訊錄、微博等),會導致頁面卡頓,滾動不流暢等性能問題,這樣就會導致移動設備耗電加快,影響移動設備的電池壽命
產生性能問題的元素:大量DOM節點的重繪和重排
優化方案:
- 懶渲染
- 可視區域渲染
懶渲染
- 懶加載,常見的長列表優化方案,常見於移動端
- 原理:每次只渲染一部分,等渲染的數據即將滾動完時,再渲染下面部分
- 優點:每次渲染一部分數據,速度快
- 缺點:數據量大時,頁面中依然存在大量DOM節點,占用內存過多,降低瀏覽器渲染性能,導致頁面卡頓
- 使用場景:數據量不大的情況下
可視區渲染(React-virtualized)
原理: 只渲染頁面可視區域的列表項,非可視區域的數據 完全不渲染(預加載前面幾項和后面幾項) ,在滾動列表時動態更新列表項
**使用場景:** 一次性展示大量數據的情況
## react-virtualized
### 概述
- 在項目中的應用:實現城市選擇列表頁面的渲染
- react-virtualized 是React組件,用來高效渲染大型列表和表格數據
- GitHub地址: [react-virtualized](https://github.com/bvaughn/react-virtualized)
### 基本使用
- 安裝: yarn add react-virtualized
- 在項目入口文件 index.js 中導入樣式文件
- 打開 [文檔](https://github.com/bvaughn/react-virtualized/blob/master/docs), 點擊List組件,進入List的文檔中
- 拷貝示例代碼到我們項目中,分析示例代碼
import React from 'react';
import ReactDOM from 'react-dom';
import { List } from 'react-virtualized';
// 列表數據
const list = [
'Brian Vaughn'
// And so on...
];
// 渲染每一行的內容
function rowRenderer ({
key, // Unique key within array of rows
index, // 索引號
isScrolling, // 當前項是否正在滾動中
isVisible, // 當前項在List中是可見的
style // 重點屬性:一定要給每一個行數添加該樣式
}) {
return (
<div
key={key}
style={style}
>
{list[index]}
</div>
)
}
// 渲染list列表
ReactDOM.render(
<List
// 組件的寬度
width={300}
// 組件的高度
height={300}
rowCount={list.length}
// 每行的高度
rowHeight={20}
rowRenderer={rowRenderer}
/>,
document.getElementById('example')
);
### 讓List組件占滿屏幕
- 利用 `AutoSizer` 組件來調整子元素的寬高
- 導入 `AutoSizer` 組件
- 通過 render-props 模式,獲取到`AutoSizer` 組件暴露的 width 和 height 屬性
- 設置List組件的 width 和 height 屬性
- 設置選擇頁面根元素高度 100%,讓List組件占滿整個頁面
- 給list組件添加onRowsRendered配置項,用於獲取當前列表渲染的行信息,在里面就會有相應信息
- 通過參數 startIndex 獲取到 起始行對應的索引號
- 判斷 startIndex 和 activeIndex 不同時候,更新狀態 activeIndex為 startIndex
<List
...
onRowsRendered={this.rowRendered}
/>
/**
* 獲取滾動時候,相應的數據
* @param {*} param0
*/
rowRendered = ({ startIndex }) => {
if (this.state.activeIndex !== startIndex) {
this.setState({
activeIndex: startIndex
})
}
}