后端一次性返回10万条数据,使用vue,你该如何渲染?

vue 解决同时加载万条级数据,页面渲染卡顿问题

1. 问题描述

由于业务需求,需要在一个页面中点击查询按钮时加载出所有的数据,但数据量有近10万条,渲染出现卡顿,页面卡死。

2. 常见的解决方案

- 自定义中间层
自定义nodejs中间层,获取并拆分这10w条数据,
前端对接nodejs中间层,而不是服务器
缺点:成本高
- 虚拟列表
只渲染可视区域DOM,其他隐藏区域不显示,只用div撑起高度,随着浏览器滚动,创建和销毁DOM。
在这里插入图片描述
虚拟列表实现起来非常复杂,可借用第三方lib
Vue-virtual-scroll-list
React-virtualiszed
- 前后端配合(本问题解决方案)
前端使用pl-table加载数据;pl-table(大数据表格,完美解决万级数据渲染卡顿问题)
后端循环获取数据,每次只获取几百条数据,获取后就进行渲染。

3. 解决方案流程图

使用pl-table + 每次从后端读取500条数据后就渲染 ,渲染完成后如果还有数据继续获取数据500条并渲染,直至数据读取完成。
流程图如下图所示:

请添加图片描述

1)点击查询按钮
2)判断是否正在查询(isSearching)
3)isSearching = true ;正在查询时判断是否需要停止,需要停止则查询结束;不需要停止则继续查询过程(不需要额外操作)。
4)isSearching = false ;没有正在查询,这时需要设置 isSearching = true;startId = 0 (查询的开始id);
searchingTaskTag = genUuid()// 随机数(用来在前后端传递,保证是同一个查询)
5)调用中间fn1函数,判断当前请求数据的最大Id是否小于等于0,如果小于等于0 则请求出最大maxId,并设置endId = startId + step(查询的结束Id);
6) 判断startId <= maxId 为true,则调用函数fn2,随机数searchingTaskTag请求和响应中携带。
7)根据response.searchingTaskTag === searchingTaskTag 判断是否是同一个请求,如果是数据则累加进去,同时 startId = startId + step;并去调用步骤5)。
8)判断startId <= maxId 为false,则结束查询。

4. 代码

  1. 查询方法
//查询
    handleSearch() {
      //this.isShow = false;
      if (this.isSearching) {
        // 提示用户是否停止查询?
        this.$confirm("确认停止查询?", "提示", {
          type: "warning",
        }).then(() => {
          this.listLoading = false;
          this.searchingTaskTag = "";
          this.isSearching = false;
          this.hardReset = false;
          this.$nextTick(() => {
            this.hardReset = true;
          });
        });
      } else {
        this.isSearching = true;
        this.searchingTaskTag = genUuid();
        this.tableData = [];
        this.startId = 0;
        this.fn1();
      }
    },
  1. 中间函数fn1
    async fn1() {
      let startId = this.startId;
      let endId = this.startId + this.step;
      let param = {
        pageNo: this.page,
        pageSize: this.pageSize,
        startId: startId,
        endId: endId,
        searchingTaskTag: this.searchingTaskTag,
      };
      try {
        if (this.maxId <= 0) {
          let response = await getMaxId();
          this.maxId = response.body;
        }
        if (startId <= this.maxId) {
          this.fn2(param);
        } else {
          this.$message.success("查询结束!");
          this.isSearching = false;
        }
      } catch (e) {}
    },
getMaxId() {
      getMaxId()
        .then((resp) => {
          this.maxId = resp.body;
        })
        .catch((error) => {
          this.$message.error(error.body);
        });
    },
 
  1. fn2 函数
   //获取数据列表
 fn2(param) {
      fn2(param).then(
      (resp) => {
          let tempList = resp.body.content;
          let echoSearchingTaskTag = resp.body.searchingTaskTag;

          if (
            tempList.length > 0 &&
            this.searchingTaskTag == echoSearchingTaskTag
          ) {
            this.tableData.push(...tempList);
           }
 

          if (this.searchingTaskTag == echoSearchingTaskTag) {
            this.listLoading = false;
            this.startId += this.step;
            this.fn1();
          }
        })
        .catch((error) => {
          this.listLoading = false;
          this.$message.error("获取失败!");
          this.isSearching = false;
          this.flag = false;
        });

                            
      this.listLoading = false;
    },
  • 5
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
引用\[1\]中的代码是一个封装了AJAX函数的示例,用于请求10w条数据。该函数使用XMLHttpRequest对象发送GET请求,并通过Promise对象返回请求结果。引用\[2\]中提到,为了减少渲染的开销,可以每次只渲染10数据,而不是一次性渲染10w条数据。这样可以避免卡顿的问题。引用\[3\]中的代码展示了一种分页渲染数据的方法,将10w条数据按照每页数量limit分成多页,利用setTimeout每次渲染一页数据,从而减少渲染时间。 对于Vue来说,如果一次性请求一万条数据,可能会导致页面卡顿或加载时间过长。为了提高性能和用户体验,可以考虑使用分页加载数据的方式。可以将数据分成多个页面,每次只请求当前页面的数据,然后根据需要进行切换和加载。这样可以避免一次性加载大量数据造成的性能问题。 另外,可以使用Vue的异步组件或者虚拟滚动等技术来优化大数据量的渲染。异步组件可以延迟加载组件,只在需要的时候才进行渲染,从而提高页面加载速度。虚拟滚动则是只渲染可见区域的数据,而不是全部渲染,从而减少渲染的开销。 总结起来,为了一次性请求一万条数据,可以考虑使用分页加载数据、异步组件或虚拟滚动等技术来提高性能和用户体验。 #### 引用[.reference_title] - *1* *3* [后端一次给你10万条数据,如何优雅展示,到底考察我什么?](https://blog.csdn.net/muzidigbig/article/details/125925704)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [vue虚拟列表,一次性拿到10w条数据](https://blog.csdn.net/weixin_49554584/article/details/128504572)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值