1、数据冻结:当数组或Object,并且数据无需修改的情况下,可使用 Object.freeze() 让性能大幅提升。在实际开发中,这种提升大约有5~10倍,倍数随着数据量递增;
2、虚拟滚动: 页面数据较多情况下 ,首次加载速度会非常慢,虚拟滚动就可以先渲染可视范围内的 dom,通过复用超出可视范围的 dom 来提高性能;
- 创建虚拟盒子显示滚动条(虚拟盒子 高度 / 宽度 根据总数据长度和每条子元素的大小来确定);
- 虚拟盒子根据可视区的盒子进行定位,以防把实际渲染内容挤出可视区;
- 实际渲染的盒子使用 translate3d 属性实现举例顶部的位置;
- 根据可视化盒子的滚动距离切割渲染数据。
<template> <div ref="list" class="infinite-list-container" @scroll="scrollEvent($event)"> <div class="infinite-list-phantom" :style="{ height: listHeight + 'px' }"></div> <div class="infinite-list" :style="{ transform: getTransform }"> <div ref="items" class="infinite-list-item" v-for="item in visibleData" :key="item.id" :style="{ height: itemSize + 'px',lineHeight: itemSize + 'px' }" >{{ item.value }}</div> </div> </div> </template> <script> export default { name:'VirtualList', props: { //所有列表数据 listData:{ type:Array, default:()=>[] }, //每项高度 itemSize: { type: Number, default:200 } }, computed:{ //列表总高度 listHeight(){ return this.listData.length * this.itemSize; }, //可显示的列表项数 visibleCount(){ return Math.ceil(this.screenHeight / this.itemSize) }, //偏移量对应的style getTransform(){ return `translate3d(0,${this.startOffset}px,0)`; }, //获取真实显示列表数据 visibleData(){ return this.listData.slice(this.start, Math.min(this.end,this.listData.length)); } }, mounted() { // 页面数据初始化 this.screenHeight = this.$el.clientHeight; this.start = 0; // 这里的截取结束位置需要根据开始位置和首屏显示的条数来确定 this.end = this.start + this.visibleCount; }, data() { return { // 可视区域高度 screenHeight:0, // 偏移量 startOffset:0, // 起始索引 start:0, // 结束索引 end:null, }; }, methods: { scrollEvent () { // 当前滚动位置 let scrollTop = this.$refs.list.scrollTop; // 此时的开始索引 this.start = Math.floor(scrollTop / this.itemSize); // 此时的结束索引 this.end = this.start + this.visibleCount; // 滚动时列表盒子的偏移量 this.startOffset = scrollTop - (scrollTop % this.itemSize); } } }; </script> <style scoped> .infinite-list-container { height: 100%; overflow: auto; position: relative; -webkit-overflow-scrolling: touch; } .infinite-list-phantom { position: absolute; left: 0; top: 0; right: 0; z-index: -1; } .infinite-list { left: 0; right: 0; top: 0; position: absolute; text-align: center; } .infinite-list-item { padding: 10px; color: #555; box-sizing: border-box; border-bottom: 1px solid #999; } </style>
https://github.com/gaogaolater/Vlist
https://blog.csdn.net/qq_40146638/article/details/103493997
3、el-bigdata-table:vue + elementUi 使用 el-table 列表,利用 el-bigdata-table 代替,不影响 el-table原有功能,useVirtual 属性可启用虚拟滚动
https://developer.aliyun.com/mirror/npm/package/el-bigdata-table/v/1.0.9
npm install el-bigdata-table -S