最近做的一个需求,当列表大概有2万条数据,又不让做成分页,如果页面直接渲染2万条数据,在一些低配电脑上可能会照成页面卡死,基于这个需求,我们来手写一个虚拟列表

思路

  1. 列表中固定只显示少量的数据,比如60条
  2. 在列表滚动的时候不断的去插入删除dom
  3. startIndex、endIndex,不断的改变这个值来获取最新的显示列表
  4. paddingTop、paddingBottom撑开容器的滚动区域

首先看一下当直接插入2万条列表时,页面的性能



可以看到火焰图中已经有了红色的部分了,dom渲染也耗时也有1s多

再来看一下当使用虚拟列表时页面的性能



从火焰图中可以看出,火焰图中一篇绿油油的,这就证明,通过虚拟列表来进行渲染使页面性能得到了极大的提升

简单的虚拟列表demo实现

我们假设有一个容器,高度为600px,列表项每个高度为30px,那么根据列表的length我们就可以计算出滚动容器的总高度,也可以知道显示60条数据的高度,我们此时可以给容器加一个paddingBottom,来撑开容器,来模拟页面应该滚动的高度

this.paddingBottom = this.allHeight - this.scrollList.length * 30

容器同时还需要paddingTop用做当容器滚动顶部数据移除后撑起scrollTop

最后我们需要监听容器的滚动事件来不断的修改paddingTop、paddingBottom、startIndex、endIndex

最终效果

最后附上所有代码

<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
width: 300px;
height: 600px;
overflow: auto;
border: 1px solid;
margin: 100px auto;
}
.item {
height: 29px;
line-height: 30px;
border-bottom: 1px solid #aaa;
padding-left: 20px;
}
</style>
</head>
<body>
<div id="app">
<button @click="add">增加</button>
<div class="container" ref="container">
<div class="scroll-wrapper" :style="style">
<div v-for="(item, index) in scrollList" :key="index" class="item">{{item}}</div>
</div>
</div>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
list: [
'测试数据'
],
startIndex: 0,
endIndex: 60,
paddingTop: 0,
paddingBottom: 0,
allHeight: 0
},
computed: {
scrollList() {
return this.list.slice(this.startIndex, this.endIndex)
},
style() {
return {
paddingTop: this.paddingTop + 'px',
paddingBottom: this.paddingBottom + 'px'
}
}
},
watch: {
list(val) {
const valLen = val.length
this.allHeight = valLen * 30
this.paddingBottom = this.allHeight - this.scrollList.length * 30
}
},
mounted() {
const container = this.$refs.container
container.addEventListener('scroll', () => {
const top = container.scrollTop
this.startIndex = Math.floor(top / 30)
this.endIndex = this.startIndex + 60 this.paddingTop = top
if (this.endIndex >= this.list.length - 1) {
this.paddingBottom = 0
return
}
this.paddingBottom = this.allHeight - 600 - top
})
},
methods: {
add() {
let arr = new Array(50000).fill(0)
arr = arr.map((item, index) => {
return index
})
this.list = [
...this.list,
...arr
]
}
}
})
</script>
</body>
</html>

性能优化:虚拟列表,如何渲染10万条数据的dom,页面同时不卡顿的更多相关文章

  1. Mvc+Dapper+存储过程分页10万条数据

    10万条数据采用存储过程分页实现(Mvc+Dapper+存储过程) 有时候大数据量进行查询操作的时候,查询速度很大强度上可以影响用户体验,因此自己简单写了一个demo,简单总结记录一下: 技术:Mvc ...

  2. 【原创】10万条数据采用存储过程分页实现(Mvc+Dapper+存储过程)

    有时候大数据量进行查询操作的时候,查询速度很大强度上可以影响用户体验,因此自己简单写了一个demo,简单总结记录一下: 技术:Mvc4+Dapper+Dapper扩展+Sqlserver 目前主要实现 ...

  3. 使用virustotal VT 查询情报——感觉远远没有微步、思科好用,10万条数据查出来5万条都有postives >0的记录,尼玛!!!

    1399 git clone https://github.com/VirusTotal/c-vtapi.git 1400 cd c-vtapi/ 1402 sudo apt-get install ...

  4. 最短时间(几秒内)利用C#往SQLserver数据库一次性插入10万条数据

    用途说明: 公司要求做一个数据导入程序,要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储.于是在网上进行查找,发现了一个比较好的解决方案,就是采用SqlBul ...

  5. java 批量插入10万条数据

    for (int i = 0; i < 100000; i++) { dbHelper.insert("INSERT aaa(name) Values ('1')"); } ...

  6. C# 使用EPPlus 秒导出10万条数据

    1.先要引用dll文件,可以直接使用vs自带的包管理,如下图: 输入 EPPlus 我这里是安装过了的所以这里显示的是卸载而不是安装. 安装成功了之后会看到这个dll文件 代码如下: //导出Exce ...

  7. MariaDB(MySql)使用储存过程和随机函数插入10万条数据

    ))default charset =utf8; #定义一个随机切割字符串的函数 delimiter // create function randStr() ) begin ) default 'A ...

  8. PHP MySQL 快速导入10万条数据

    项目背景 数据来源:所有数据均为外部导入,最大数据量在10w+ 输出数据:导出经过业务处理之后的数据 使用框架:fastadmin 涉及的问题: 1.数据读取 2.数据保存 使用数据:10w+ 解决方 ...

  9. JavaScript如何一次性展示几万条数据

    有一位同事跟大家说他在网上看到一道面试题:“如果后台传给前端几万条数据,前端怎么渲染到页面上?”,如何回答? 于是办公室沸腾了, 同事们讨论开了, 你一言我一语说出自己的方案. 有的说直接循环遍历生成 ...

随机推荐

  1. 前端利器躬行记(3)——webpack基础

    webpack是一个静态模块打包器,此处的模块可以是任意文件,包括Sass.TypeScript.模板和图像等.webpack可根据输入文件的依赖关系,打包输出浏览器可识别的JavaScript.CS ...

  2. ParquetDecodingException: Can not read value at 0 in block -1 in file hdfs:...

    : jdbc:hive2://master01.hadoop.dtmobile.cn:1> select * from cell_random_grid_tmp2 limit 1; INFO : ...

  3. Spring框架介绍及使用(转载)

    原文链接 Spring框架—控制反转(IOC) 1 Spring框架概述1.1 什么是SpringSpring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod ...

  4. c# webapi结合swagger的使用

    一.使用nuget下载swagger包 Install-Package Swashbuckle 二.配置swagger 1. 安装完Swashbuckle后,nuget会将相关引用添加至WebApi项 ...

  5. dmg文件转iso格式

    1. 简介 dmg是MAC苹果机上的压缩镜像文件,相当于在Windows上常见的iso文件. dmg格式在苹果机上可以直接运行加载,在Windows平台上需要先转换为iso格式. 2. 转换工具 本文 ...

  6. 2019 Multi-University Training Contest 1

    2019 Multi-University Training Contest 1 A. Blank upsolved by F0_0H 题意 给序列染色,使得 \([l_i,r_i]\) 区间内恰出现 ...

  7. lightoj 1283 - Shelving Books(记忆化搜索+区间dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1283 题解:这题很显然一看就像是区间dp,但是单纯的区间dp好像解决不了问题可 ...

  8. codeforces 814 D. An overnight dance in discotheque (贪心+bfs)

    题目链接:http://codeforces.com/contest/814/problem/D 题意:给出奇数个舞者,每个舞者都有中心坐标和行动半径,而且这些点组成的园要么相互包含要么没有交集求,讲 ...

  9. hdu2586 How far away ?(lca模版题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵树还有两个点然后求这两个点的最短距离. 题解:val[a]+val[b]-2*va ...

  10. 漫谈JavaScript中的作用域(scope)

    什么是作用域 程序的执行,离不开作用域,也必须在作用域中才能将代码正确的执行. 所以作用域到底是什么,通俗的说,可以这样理解:作用域就是定义变量的位置,是变量和函数的可访问范围,控制着变量和函数的可见 ...