Antd中的Table數(shù)據(jù)異步動(dòng)態(tài)加載性能優(yōu)化

需求

利用Antd的Table組件可以實(shí)現(xiàn)表格的展示,表格數(shù)據(jù)是動(dòng)態(tài)增加的,并且表格數(shù)據(jù)的請(qǐng)求為異步請(qǐng)求。當(dāng)數(shù)據(jù)條數(shù)較大時(shí),需保證加載速度。

初始代碼結(jié)構(gòu):

首先,頁(yè)面結(jié)構(gòu)如下:

  render() {
    const {showProcess, data, length} = this.state
    return (
      <>
        <Table
          columns={tableHead} 
          dataSource={data} 
        ></Table>
        <Modal
         visible={showProcess}
        > 
          <Progress 
            type="circle"
            percent={parseInt(`${(data.length / length) * 100}`)} 
          />
        </Modal>
      </>
    );
  }

Table為Antd中的表格,表格數(shù)據(jù)為data,最終的總數(shù)據(jù)長(zhǎng)度為length,length為已知數(shù)據(jù)。Modal為顯示數(shù)據(jù)加載進(jìn)程的彈出框,加載進(jìn)程根據(jù)數(shù)據(jù)加載條數(shù)決定,其顯示狀態(tài)由showProcess控制。

動(dòng)態(tài)加載部分:

  componentDidMount(){
    const {data, length} = this.state
    let i = 1
    //異步動(dòng)態(tài)加入數(shù)據(jù)
    let interval = setInterval(() => {
      if(i<= length){
        data.push({
          key: String(i),
          order: String(i),
          name: '張三',
          age: 13,
          hobby: '乒乓',
          home: '山東',
        })
        this.setState({data: data})
        console.log(i)
        i++
      }else{
        //數(shù)據(jù)加載全部完成,取消Modal框并清除interval
        this.setState({showProcess: false})
        clear()
      }
    }, 10);

    let clear=()=>{
      clearInterval(interval)
    }
  }

由于需要?jiǎng)討B(tài)載入,則需將數(shù)據(jù)的動(dòng)態(tài)填充放入componentDidMount中,它是在render函數(shù)之后執(zhí)行的。

代碼問(wèn)題:以上代碼可以實(shí)現(xiàn)數(shù)據(jù)動(dòng)態(tài)加載效果,但是如果數(shù)據(jù)條數(shù)較大時(shí),會(huì)出現(xiàn)加載緩慢問(wèn)題。加載緩慢原因是由于每次Push一條數(shù)據(jù)時(shí),都對(duì)表格數(shù)據(jù)進(jìn)行了更新,每一次更新都會(huì)觸發(fā)render函數(shù)的執(zhí)行,DOM操作較大,影響性能。

優(yōu)化后代碼

為了解決加載速度慢的問(wèn)題,可采取前20條數(shù)據(jù)載入后更新Table的data狀態(tài),以便于頁(yè)面視覺(jué)上保證數(shù)據(jù)一條條增加,而后面的數(shù)據(jù)可全部加載完再塞入Table中,避免頻繁的觸發(fā)render,影響性能。
以下為更改后的異步請(qǐng)求數(shù)據(jù)的函數(shù):

    let interval = setInterval(() => {
      if(i<= length){
        data.push({
          key: String(i),
          order: String(i),
          name: '張三',
          age: 13,
          hobby: '乒乓',
          home: '山東',
        })
        //新增代碼,加入判斷條件
        if(i<=20){
          this.setState({data: data})
        }
        console.log(i)
        i++
      }else{
        //數(shù)據(jù)加載全部完成,取消Modal框并清除interval
        this.setState({showProcess: false})
        //新增代碼,完成后統(tǒng)一setState data
        this.setState({data: data})
        clear()
      }
    }, 10);

以上代碼可以實(shí)現(xiàn)頁(yè)面加載速度的提高,但這樣Modal組件中的data也不會(huì)動(dòng)態(tài)更新了,如果動(dòng)態(tài)更新數(shù)據(jù)長(zhǎng)度,那render函數(shù)也會(huì)動(dòng)態(tài)執(zhí)行,因此將Modal組件分割為一個(gè)子組件,每次數(shù)據(jù)動(dòng)態(tài)載入后,都觸發(fā)該子組件中的方法,增加其數(shù)據(jù)長(zhǎng)度。

Modal子組件中加入以下方法:

  //關(guān)閉Modal提示
  close = () => {
    this.setState({showProcess: false})
  }
  //組件中的數(shù)據(jù)長(zhǎng)度增加
  addLength = () => {
    const {curLen} = this.state
    this.setState({curLen: curLen + 1})
  }

總長(zhǎng)度length以屬性方法傳入子組件,curLen為加載了的數(shù)據(jù)長(zhǎng)度。

父組件:

    let interval = setInterval(() => {
      if(i<= length){
        data.push({
          key: String(i),
          order: String(i),
          name: '張三',
          age: 13,
          hobby: '乒乓',
          home: '山東',
        })
        if(i<=20){
          this.setState({data: data})
        }
        console.log(i)
        //新增代碼
        this.refs["modal"].addLength()
        i++
      }else{
        //數(shù)據(jù)加載全部完成
        this.setState({data: data})
        //新增代碼
        this.refs["modal"].close()
        clear()
      }
    }, 10);

以上為用Typescript寫(xiě)的,以下附上ref的引用方式:
父組件中寫(xiě)入以下代碼即可使用ref。

refs:{
    [key: string]: (any); // 類型聲明
    modal:ModalProcess;
  }
//引用
<ModalProcess ref = 'modal' length={length}/>

以上即解決了異步動(dòng)態(tài)加載過(guò)程中頻繁觸發(fā)render函數(shù)造成界面加載速度過(guò)慢的問(wèn)題。總結(jié)為:1. 不要頻繁觸發(fā)render,可以數(shù)據(jù)全部加載完后再觸發(fā)。 2. 如果必須一直需要?jiǎng)討B(tài)更新的,可以寫(xiě)入到子組件中,父組件調(diào)用子組件的方法以實(shí)現(xiàn)數(shù)據(jù)更新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說(shuō)明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí),會(huì)觸發(fā)此異常。 O...
    我想起個(gè)好名字閱讀 6,023評(píng)論 0 9
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,328評(píng)論 2 89
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,692評(píng)論 4 61
  • 不只有一個(gè)老師、前輩跟我交流分享,問(wèn)我:"你有什么優(yōu)點(diǎn)?" 我:"我其實(shí)沒(méi)什么優(yōu)點(diǎn)的"我實(shí)在是在幾秒的停頓里努力去...
    三歲的世界hh閱讀 412評(píng)論 0 3
  • 書(shū)看完了,感覺(jué)受益匪淺,家庭教育真是太重要了,之前一直是壓制孩子不讓其釋放自己的天性,真的很感謝文化姐推薦的這本書(shū)...
    255b13afce2f閱讀 238評(píng)論 0 0

友情鏈接更多精彩內(nèi)容