性能优化:虚拟列表,如何渲染10万条数据的dom,页面同时不卡顿
最近做的一个需求,当列表大概有2万条数据,又不让做成分页,如果页面直接渲染2万条数据,在一些低配电脑上可能会照成页面卡死,基于这个需求,我们来手写一个虚拟列表
思路
- 列表中固定只显示少量的数据,比如60条
- 在列表滚动的时候不断的去插入删除dom
- startIndex、endIndex,不断的改变这个值来获取最新的显示列表
- 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,页面同时不卡顿的更多相关文章
- Mvc+Dapper+存储过程分页10万条数据
10万条数据采用存储过程分页实现(Mvc+Dapper+存储过程) 有时候大数据量进行查询操作的时候,查询速度很大强度上可以影响用户体验,因此自己简单写了一个demo,简单总结记录一下: 技术:Mvc ...
- 【原创】10万条数据采用存储过程分页实现(Mvc+Dapper+存储过程)
有时候大数据量进行查询操作的时候,查询速度很大强度上可以影响用户体验,因此自己简单写了一个demo,简单总结记录一下: 技术:Mvc4+Dapper+Dapper扩展+Sqlserver 目前主要实现 ...
- 使用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 ...
- 最短时间(几秒内)利用C#往SQLserver数据库一次性插入10万条数据
用途说明: 公司要求做一个数据导入程序,要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储.于是在网上进行查找,发现了一个比较好的解决方案,就是采用SqlBul ...
- java 批量插入10万条数据
for (int i = 0; i < 100000; i++) { dbHelper.insert("INSERT aaa(name) Values ('1')"); } ...
- C# 使用EPPlus 秒导出10万条数据
1.先要引用dll文件,可以直接使用vs自带的包管理,如下图: 输入 EPPlus 我这里是安装过了的所以这里显示的是卸载而不是安装. 安装成功了之后会看到这个dll文件 代码如下: //导出Exce ...
- MariaDB(MySql)使用储存过程和随机函数插入10万条数据
))default charset =utf8; #定义一个随机切割字符串的函数 delimiter // create function randStr() ) begin ) default 'A ...
- PHP MySQL 快速导入10万条数据
项目背景 数据来源:所有数据均为外部导入,最大数据量在10w+ 输出数据:导出经过业务处理之后的数据 使用框架:fastadmin 涉及的问题: 1.数据读取 2.数据保存 使用数据:10w+ 解决方 ...
- JavaScript如何一次性展示几万条数据
有一位同事跟大家说他在网上看到一道面试题:“如果后台传给前端几万条数据,前端怎么渲染到页面上?”,如何回答? 于是办公室沸腾了, 同事们讨论开了, 你一言我一语说出自己的方案. 有的说直接循环遍历生成 ...
随机推荐
- Netty源码分析 (一)----- NioEventLoopGroup
提到Netty首当其冲被提起的肯定是支持它承受高并发的线程模型,说到线程模型就不得不提到NioEventLoopGroup这个线程池,接下来进入正题. 线程模型 首先来看一段Netty的使用示例 pa ...
- Calendar常用方法
import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; public class C ...
- HTML(一)简介,元素
HTML简介 html实例: <!DOCTYPE html> 菜鸟教程 我的第一个标题 我的第一个段落 实例解析: <!DOCTYPE html> 声明为 HTML5 文档,不 ...
- 【selenium】- 自动化框架环境搭建
本文由小编根据慕课网视频亲自整理,转载请注明出处和作者. 1. 环境搭建 本课程选用的是selenium + java. 2. java环境的搭建 环境变量配置: 以win10为例,打开控制面板& ...
- Codeforces Round #465 &935C. Fifa and Fafa计算几何
传送门 题意:在平面中,有一个圆,有一个点,问能在这个圆中围出最大的圆的圆心坐标和半径.要求这个最大圆不包含这个点. 思路:比较基础的计算几何,要分三种情况,第一种就是这个点在圆外的情况.第二种是点在 ...
- Codeforces 919D Substring (拓扑排序+树形dp)
题目:Substring 题意:给你一个有向图, 一共有n个节点 , m条变, 一条路上的价值为这个路上出现过的某个字符最多出现次数, 现求这个最大价值, 如果价值可以无限大就输出-1. 题解:当这个 ...
- 跟我学SpringCloud | 第十七篇:服务网关Zuul基于Apollo动态路由
目录 SpringCloud系列教程 | 第十七篇:服务网关Zuul基于Apollo动态路由 Apollo概述 Apollo相比于Spring Cloud Config优势 工程实战 示例代码 Spr ...
- 人体行为识别(骨架提取),搭建openpose环境,VS2019(python3.7)+openpose
这几天开始接触人体行为识别,经过多方对比后,选择了现在最热的人体骨架提取开源库,openpose. 下面就不多说了,直接开始openpose在win10下的配置: 需求如下:1. VS2019 ...
- fireFox模拟 post请求、上传插件,火狐浏览器中文postman插件
ApiPost是一个支持团队协作,支持模拟POST.GET.PUT等常见请求,并可直接生成文档的API调试.管理工具. 它拥有以下功能特性: 1.文档管理ApiPost不仅可以快速生成接口文档,还支持 ...
- java中的equals方法与"=="运算符解说
在编程的时候,我们可能经常会用到equals方法,那么这个equals方法和运算符“==”有什么样的区别? public class equal { /** * @param args */ publ ...