vue页面加载海量数据(table)

1,046 阅读1分钟

table加载海量数据

个人已知的页面海量数据加载方式包括

  • 前端对海量数据分页手动分页。
  • 在1的基础上监听滚动、动态加载前端缓存数据。

然后我突然脑子一抽,想试试完整的对页面进行4w数据的渲染。最终实现方案vue 方案三、方案四为jquery

模拟数据

let data = [];

for (let i = 0; i <= 4000; i++) {
  let item = {
    id: i,
    name: "江苏德邦集成吊顶股份有限公司",
    area: "江苏省连云港市连云区",
    time: "2020-4",
    level: "一级",
    judge: "存在隐患",
    source: "文件上传",
    status: "审核中",
    operation: "审核",
  };

  data.push(item);
}

公用方法

 /**
     * @description 将海量数据进行分组
     * @param { Array } arrsy 分组的数据
     * @param { number } size  每组多少个
     */
    chunkArrayFun(array, size) {
      let arr = [];
      let index = 0;

      for (let i = 0; i < array.length; i += size) {
        let chunkArr = [];

        for (let j = 0; j < size; j++) {
          chunkArr[j] = array[index++];
          if (index == array.length) break;
        }

        arr.push(chunkArr);
      }

      return arr;
    },

尝试一

直接一把嗦,将四万条数据 一口气赋值进去。

大概页面白屏了 一分十秒左右

尝试二

将四万条数据进行分组,然后通过settimeOut进行分批次加载

  let arr = this.chunkArrayFun(data, 600);

  for (let i = 0; i < arr.length; i++) {
    setTimeout(() => {
      this.tableData.push(...arr[i]);
    }, 10);
  }

页面加载时间为八秒左右。 出现的问题包括:

  • 滑动时会出现明显的卡顿
  • 滑动过快时会出现明显的白屏

问题分析: 可能是因为不停的在push数据导致整个table组件不停的重绘导致的问题。

尝试三

利用element-table中的append的插槽, 在一个table中嵌入多个表格,再对每个表格进行单独的赋值,避免整个table组件不停的重绘,效果如下图:

代码如下

<el-table :data="[]" style="width: 100%">
        <template slot="empty">
          <div></div>
        </template>
        <el-table-column prop="id" label="序号" width="100"></el-table-column>
		...
        <el-table-column prop="operation" label="操作"></el-table-column>
        <template v-slot:append>
          <el-table
            :data="chunkArray[index]"
            v-for="(item, index) of chunkArray"
            :key="index"
            style="width: 100%"
            :show-header="false"
          >
            <el-table-column
              :prop="v.key"
              :label="v.name"
              v-for="(v, i) of tableHead"
              :key="i"
              :width="v.width|| ''"
            ></el-table-column>
          </el-table>
        </template>
      </el-table>
      
js
 tableHead: [
        { name: "序号", key: "id", width: 100, },
        ...
        { name: "操作", key: "operation", width: "",},
 ],
 
 this.tableData = this.chunkArrayFun(data, 600);
  
 this.$nextTick(() => {
  for (let i = 0; i < this.tableData.length; i++) {
    setTimeout(() => {
      this.chunkArray[i].push(...this.tableData[i]);
    }, 10);
  }
});

页面展示:1~2秒。至于最后多久能加载完没算。没有白屏的情况出现

存在问题:滑动时还是存在一定的卡顿。但比之前要好很多。

最终实现效果如下

尝试四

我试了一下使用(jquery+异步分批)直接操作dom进行渲染。

页面展示:贼快。

存在的问题:分组太大时、滚轮滑动过快,可能会出现一定的白屏状况。 分组100就不会这样的情况了

结论:jquery 天下第一

let data = this.chunkArrayFun(stashData, 100);

for (let i = 0; i < data.length; i++) {
  setTimeout(() => {
    this.setHtml(data[i]);
  }, 20);
}

setHtml(data) {
  let str = ``;
  data.forEach((item) => {
    let trItem = `<tr>`;
    for (let key in item) {
      trItem += `<td>${item[key]}</td>`;
    }

    trItem += `</td>`;
    str += trItem;
  });
  this.$nextTick(() => {
    $(".hugeTable").append(str);
  });
},

效果如下

使用vue进行渲染不可避免的需要对data每个属性进行双向绑定(伪),而且将html进行虚拟dom的转换都需要一定的运算成本。

而jquery直接操作dom,省去了中间商赚差价。丝滑顺畅。