处理el-table大数据卡顿的问题,包含tree型数据格式

文章目录

    • 概要
    • 技术细节
    • 小结

概要

如果你有更丰富的表格需求,可以查看我另一篇文章 关于vxe-table的使用心得及扩展

1、现象

有时候el-table的数据可能有成千上万条,而且又要在一页显示完,这时候页面渲染的dom太多了,可能会造成页面卡顿。

解决方案:给表格固定高度,只渲染用户在表格中滚动的视图dom

2、卡顿原因

因为数据量过多导致浏览器渲染过多的标签元素 导致DOM树占用内存较大 使得用户操作阻塞。

具体原理可参考别的大佬写的文章:DOM性能瓶颈与Javascript性能优化.

3、解决方法及原理

原理

解决思路可参考: 页面中长列表滚动的优化.

解决方法

使用第三方插件 npmjs.com/package/pl-ta

技术细节

  
  
    pl-table在线预览,更多玩法请看文档哦,欢迎Star
    去子页面(为了测试缓存组件)
    
      全选
      清除选中
      变化数据为3条
      变化数据为200条
      变化数据为1000条
      滚动到1千位置
      滚动到2千位置
      滚动到顶部
      滚动到底部位置
      设置高度为400
      设置高度为300
    
 
    
    
      

我是Y轴虚拟

没有查询到符合条件的记录

我是X + Y轴同时虚拟

我是加入分页的表格

没有查询到符合条件的记录

我是普通的el-table树形表格,这个数据多了就卡,这就是原本的el-table树表格,必须指定 row-key

没有查询到符合条件的记录

我是pl-table大数据树形表格 必须指定 row-key 必须开启use-virtual

切换第一个 展开第三个 展开全部 关闭所有 获取已展开 没有查询到符合条件的记录 // 下面是关于pl-table的树形数据的介绍,希望读完下面的文字 // (最大数量500)当然你可以更多,那么只会导致你遍历时间多,页面等待时间长,(并非渲染节点时间长) // 另外 就以下的这个层级,总数据量展开后,就是 500 + 500 x 3 + 3 x 1 = 2003 的总数据量 // 如果你 第一级是500, 第二级也是500, 第三级是10。那么你的数据量就是 500 + 500 x 500 + 500 x 10 的总数据量,这是非常吓人的 // 所以结合自己情况去给树数据,不要瞎乱给下面的数据,树节点避免不鸟去递归,如果你的数据量很大很大,那么你会死在遍历上。 // 注意,注意,注意:并非第一级不能超过500,是想告诉你们嵌套里面子节点层级数据量不要太大。比如你可这样的:第一级为1000, 第二级为2-5的数据量, // 第三级为2-5的数据量...., 那么这样算下来,就是 1000 + 1000 x 5 + 5 x 5 = 6025的数据量,应该是可以的,但是记住要是太大的嵌套数据。那只会导致 // 程序卡在遍历数据上,因为程序需要慢慢去递归遍历。这是没有办法的。 // 但是传统el-table 或者el-tree他们数据量超过200 就会卡。所以我们已经很好的优化了这一点。不过看来对于树形数据的要求,应该数据量不会太大。 // 你可以在pl-table的基础上去改改样式,就可以变相的去实现el-tree的组件了哦,你隐藏下头部,把行的高度给小一点。然后隐形边框线。是不是就是el-tree了呢??? var dataList = Array.from({ length: 500 }, (_, idx) => ({ id: idx + "_" + 1, date: "2016-05-03", name: 1, ab: "欢迎使用pl-table", address: idx, children: Array.from({ length: 3 }, (_, idx2) => ({ id: idx + "_" + idx2 + "_" + 1, date: "2016-05-03", name: 1, ab: "欢迎使用pl-table", address: idx + "_" + idx2, children: Array.from({ length: 1 }, (_, idx3) => ({ id: idx + "_" + idx2 + "_" + idx3 + "_" + 1, date: "2016-05-03", name: 1, ab: "欢迎使用pl-table", address: idx + "_" + idx2 + "_" + idx3 })) })) })); export default { name: "home", data() { return { rowHeight: 50, columns: [ { prop: "address", label: "日期", width: 120, treeNode: true, showOverflowTooltip: true }, { prop: "address", label: "地址", width: 100, showOverflowTooltip: true }, { prop: "address", label: "噜噜噜", width: 230, showOverflowTooltip: true }, { prop: "address", label: "娃哈哈", width: 100, showOverflowTooltip: true }, { prop: "address", label: "地址", width: 100, showOverflowTooltip: true }, { prop: "address", label: "娃哈哈", width: 100, showOverflowTooltip: true }, { prop: "address", label: "娃哈哈", width: 100, showOverflowTooltip: true }, { prop: "address", label: "地址", width: 100, showOverflowTooltip: true }, { prop: "address", label: "娃哈哈", width: 100, showOverflowTooltip: true }, { prop: "address", label: "娃哈哈", width: 100, showOverflowTooltip: true }, { prop: "address", label: "噜噜噜", showOverflowTooltip: true }, { prop: "address", label: "娃哈哈", width: 100, showOverflowTooltip: true, fixed: "right" } ], columns2: Array.from({ length: 20 }, (_, idx) => ({ prop: "address", label: "地址" + idx, width: 200, showOverflow: true, sortable: true, fixed: "" })), data: { tableData: Array.from({ length: 10000 }, (_, idx) => ({ id: idx + 1, date: "2016-05-03", name: 1, ab: "欢迎使用pl-table", address: 1 + idx })) }, top: 0, height: 500, pageForm: { total: 1000, pageSize: 10, currentPage: 1 }, treeData: dataList }; }, methods: { selectAll(val) { console.log(val); }, selectable(row, index) { if (index === 1) { return false; } else { console.log(row,index); return true; } }, // 合计 summaryMethod({ columns, data }) { // 平均值算法(不需要自己去掉) function cacl(arr, callback) { let ret; for (let i = 0; i < arr.length; i++) { ret = callback(arr[i], ret); } return ret; } // 平均值算法(不需要自己去掉) Array.prototype.sum = function() { return cacl(this, function(item, sum) { if (typeof sum == "undefined") { return item; } else { return (sum += item); } }); }; // 平均值算法(不需要自己去掉) Array.prototype.avg = function() { if (this.length == 0) { return 0; } return this.sum(this) / this.length; }; const means = []; // 合计 const fenceSums = []; // 平均值 columns.forEach((column, columnIndex) => { if (columnIndex === 0) { means.push("合计"); fenceSums.push("平均值"); } else { const values = data.map(item => Number(item[column.property])); // 合计 if (!values.every(value => isNaN(value))) { means[columnIndex] = values.reduce((prev, curr) => { const value = Number(curr); if (!isNaN(value)) { return prev + curr; } else { return prev; } }, 0); // means[columnIndex] += ' 元' // 改变了ele的合计方式,扩展了合计场景 // 你以为就只有上面这样玩吗?错啦,你还可以自定义样式哦 // means[columnIndex] = '' + means[columnIndex] + '元' means[columnIndex] = '' + means[columnIndex] + "元
123"; } else { means[columnIndex] = ""; } // 平均值 const precisions = []; let notNumber = true; values.forEach(value => { if (!isNaN(value)) { notNumber = false; let decimal = ("" + value).split(".")[1]; precisions.push(decimal ? decimal.length : 0); } }); if (!notNumber) { fenceSums[columnIndex] = values.avg(); } else { fenceSums[columnIndex] = ""; } } }); // 返回一个二维数组的表尾合计 return [means, fenceSums]; }, setHei(val) { this.height = val; }, tableBodyScroll({ scrollTop }) { this.top = scrollTop; }, allSelection() { this.$refs.plTable.toggleAllSelection(); }, clearSelection() { this.$refs.plTable.clearSelection(); this.$refs.plTable2.clearSelection(); }, setData(num) { this.data.tableData = Array.from({ length: num }, (_, idx) => ({ id: idx + 1, date: "2016-05-03", name: 1, ab: "欢迎使用pl-table", address: 1 + idx })); }, scrollBottom() { this.$refs.plTable.scrollBottom(); }, pagingScrollTopLeft(val) { this.$refs.plTable.pagingScrollTopLeft(val, 0); }, // 分页事件 handlePageSize({ page, size }) { console.log(page, size); }, // 获取已经展开的节点 getTreeExpansionEvent() { console.log(this.$refs.plTreeTable.getTreeExpandRecords()); } } }; body, html { margin: 0; box-sizing: border-box; width: 100%; height: 100%; } body ::-webkit-scrollbar-thumb { -webkit-border-radius: 5px; border-radius: 5px; background-color: rgba(144, 147, 153, 0.5); } .selectTr td { background: #ccc !important; color: red !important; }

小结

此搬运是为了防止地址失效,原作者在下方

感谢原文地址

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/6787848180.html