虚拟列表渲染-前端性能优化

目录

1 使用场景

2 小插曲

3 虚拟列表渲染实现原理

 4 代码实现


1 使用场景

在做EMBP项目时,有个模板新建的需求,需要点击获取子任务时获取所有的子任务,当时有的数据比较大,会有几百条的情况,此时接口请求变得很慢(这个后端做了优化),但是由于数据较多,前端渲染起来特别慢,最后通过度哥,学习了下前端渲染机制,最终通过虚拟列表渲染在前端做了优化。

2 小插曲

在此期间对前端的事件执行进行了学习,更好的了解了事件的执行顺序及时机。如下图,学习后发现可以通过添加定时器的方式来计算dom的渲染时间

在获取到数据后执行

let date1 = new Date();// 数据获取后执行

setTimeout(()=>{//setTimeout是一个宏任务 会等待ui渲染完成后执行

  let data2 = new Date();// dom渲染后执行

},0)

3 虚拟列表渲染实现原理

(1)通过一条数据的高度及所有数据的长度获取到所有数据的高度(暂叫h1),在需要使用虚拟列表的同级地方添加一个div,高度设置成h1,

(2)在需要添加虚拟列表的dom中,将高度设置成其对应可视区的高度(暂叫h2)

(3)给需要添加虚拟列表的dom添加一个父级,将其高度设置成h2

(4)通过(1)来给对应可视区设置滚动,通过(3)来给虚拟列表添加定位,然后在滚动时,修改虚拟列表的top来实现虚拟列表永远出现在可视区内。

 4 代码实现

(1)对应dom代码片段

<div class="list_view" ref="listView" @scroll="handleScroll" style="height:530px;overflow-y:auto;position: absolute;width:100%;z-index:9999;">
   <!-- 表格内容 -->
   <el-table :data="showList" ref="content" class="list_view_content" style="height:530px;position: absolute;width:100%;" :style="{top:scrollTop + 'px'}">
    </el-table>
    <div class="scroll_area" :style="{ height: scrollAreaHeight }"></div>
</div>

(2)在data中设置变量

showNum: 10,//显示几条数据
start: 0,//滚动过程显示的开始索引
end: 10,//滚动过程显示的结束索引
itemHeight: 30,
list: [],
scrollTop: 0,

(3)在computed计算内容总高度及虚拟列表需要显示的数据

computed: {
  //内容总高度
  scrollAreaHeight() {
    return this.sonTableData.length * this.itemHeight + 'px';
  },
  //区可视的数据, 
  showList() {
    return this.sonTableData.slice(this.start, this.end); 
  }
},

 (4)在methods中需要使用的方法

//计算滚动
computescrollArea(scrollTop) {
  scrollTop = scrollTop || 0;  

 scrollTop = scrollTop || 0;  
    this.showNum = Math.ceil(this.$refs.listView.clientHeight / this.itemHeight) - 1; // 取得可见区域的可见列表项数量-减去表头的高度
    //开始的数组索引     滚到第几条数据  =  滚动高度   /  每个item的高度 
    this.start = Math.floor(scrollTop / this.itemHeight) + 1; 
    //结束索引    可视的数据 = 滚到第几条数据  + 显示几条数据
    this.end = this.start + this.showNum + 1; 
    //绝对定位对相对定位的偏移量   已滚动的高度 = 滚到第几条数据  * 每个item的高度 
    this.$refs.content.style.webkitTransform = `translate3d(0, ${this.start * this.itemHeight}px, 0)`; 
    // this.$refs.content.style.webkitTransform = `translateY(${start * this.itemHeight}px)`;    
},
//滚动触发
handleScroll() {
  //获取已滚动的高度
  console.log("this.$refs.listView.scrollTop--",this.$refs.listView.scrollTop)
  // const scrollTop = this.$refs.listView.scrollTop;
  // this.computescrollArea(scrollTop);
  this.scrollTop = this.$refs.listView.scrollTop;
  this.computescrollArea(this.scrollTop);
},

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值