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,省去了中间商赚差价。丝滑顺畅。