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

需求

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

初始代码结构:

首先,页面结构如下:

  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中的表格,表格数据为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;
  }
//引用
<ModalProcess ref = 'modal' length={length}/>

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,898评论 0 9
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 32,265评论 2 89
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,833评论 4 61
  • 不只有一个老师、前辈跟我交流分享,问我:"你有什么优点?" 我:"我其实没什么优点的"我实在是在几秒的停顿里努力去...
    三岁的世界hh阅读 409评论 0 3
  • 书看完了,感觉受益匪浅,家庭教育真是太重要了,之前一直是压制孩子不让其释放自己的天性,真的很感谢文化姐推荐的这本书...
    255b13afce2f阅读 237评论 0 0

友情链接更多精彩内容