react長列表性能優化


長列表性能優化

概述

在展示大型列表和表格數據的時候(城市列表、通訊錄、微博等),會導致頁面卡頓,滾動不流暢等性能問題,這樣就會導致移動設備耗電加快,影響移動設備的電池壽命

產生性能問題的元素:大量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
        })
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM