Antd中的Table数据异步动态加载性能优化

需求

利用Antd的Table组件可以实现表格的展示,表格数据是动态增加的,并且表格数据的请求为异步请求。当数据条数较大时,需保证加载速度。

初始代码结构:

首先,页面结构如下:

  render() {
    const {showProcess, data, length} = this.state
    return (
      <>
        
); }

Table为Antd中的表格,表格数据为data,最终的总数据长度为length,length为已知数据。Modal为显示数据加载进程的弹出框,加载进程根据数据加载条数决定,其显示状态由showProcess控制。

动态加载部分:

  componentDidMount(){
    const {data, length} = this.state
    let i = 1
    //异步动态加入数据
    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{
        //数据加载全部完成,取消Modal框并清除interval
        this.setState({showProcess: false})
        clear()
      }
    }, 10);

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

由于需要动态载入,则需将数据的动态填充放入componentDidMount中,它是在render函数之后执行的。

代码问题:以上代码可以实现数据动态加载效果,但是如果数据条数较大时,会出现加载缓慢问题。加载缓慢原因是由于每次Push一条数据时,都对表格数据进行了更新,每一次更新都会触发render函数的执行,DOM操作较大,影响性能。

优化后代码

为了解决加载速度慢的问题,可采取前20条数据载入后更新Table的data状态,以便于页面视觉上保证数据一条条增加,而后面的数据可全部加载完再塞入Table中,避免频繁的触发render,影响性能。
以下为更改后的异步请求数据的函数:

    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{
        //数据加载全部完成,取消Modal框并清除interval
        this.setState({showProcess: false})
        //新增代码,完成后统一setState data
        this.setState({data: data})
        clear()
      }
    }, 10);

以上代码可以实现页面加载速度的提高,但这样Modal组件中的data也不会动态更新了,如果动态更新数据长度,那render函数也会动态执行,因此将Modal组件分割为一个子组件,每次数据动态载入后,都触发该子组件中的方法,增加其数据长度。

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

  //关闭Modal提示
  close = () => {
    this.setState({showProcess: false})
  }
  //组件中的数据长度增加
  addLength = () => {
    const {curLen} = this.state
    this.setState({curLen: curLen + 1})
  }

总长度length以属性方法传入子组件,curLen为加载了的数据长度。

父组件:

    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{
        //数据加载全部完成
        this.setState({data: data})
        //新增代码
        this.refs["modal"].close()
        clear()
      }
    }, 10);

以上为用Typescript写的,以下附上ref的引用方式:
父组件中写入以下代码即可使用ref。

refs:{
    [key: string]: (any); // 类型声明
    modal:ModalProcess;
  }
//引用

以上即解决了异步动态加载过程中频繁触发render函数造成界面加载速度过慢的问题。总结为:1. 不要频繁触发render,可以数据全部加载完后再触发。 2. 如果必须一直需要动态更新的,可以写入到子组件中,父组件调用子组件的方法以实现数据更新。

你可能感兴趣的:(Antd中的Table数据异步动态加载性能优化)