性能优化:虚拟列表,如何渲染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如何一次性展示几万条数据
有一位同事跟大家说他在网上看到一道面试题:“如果后台传给前端几万条数据,前端怎么渲染到页面上?”,如何回答? 于是办公室沸腾了, 同事们讨论开了, 你一言我一语说出自己的方案. 有的说直接循环遍历生成 ...
随机推荐
- 关于前端jsonp跨域和一个简单的node服务搭建
先讲下概念 同源策略:是一种约定,浏览器最核心最基本的安全功能,(同域名,同协议,同端口)为同源 跨域: 跨(跳):范围 域 (源):域名,协议,端口 域名:ip的一种昵称(为了更好记住ip地址)如: ...
- 设计模式(C#)——10享元模式
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 前言 在软件开发中,当我们需要对某些对象重复创建,且最终只需要得到单一结果.如果使用一般思维,那我们将浪费很多内存空 ...
- 学测试,看视频?NONONO,除非这种情况
001 前言 : 很久没周末写文章了,一个是要睡懒觉.另外一个是,周末写了大家也没有心思看(加班1周了,好不容易周末,你又让我学习 ?先睡个懒觉再说,去TM的学习). 然而,今天早早的5点就起床了,处 ...
- HDU2767Proving Equivalences tarjan缩点,如何求入度和出度最大值
给定一个有向图,问最少增加多少条边后变成强连通图 tarjan求求强连通分量并缩点,如果强连通分量个数为1,则需要边数为0, 否则为缩点后点入度和出度的最大值, 证明:当入度或者出度不为0时 ...
- SPOJ - QTREE4 Query on a tree IV 边分治
题目传送门 题意:有一棵数,每个节点有颜色,黑色或者白色,树边有边权,现在有2个操作,1修改某个点的颜色, 2询问2个白点的之前的路径权值最大和是多少. 题解: 边分治思路. 1.重构图. 因为边分治 ...
- CodeForces 601B Lipshitz Sequence
Lipshitz Sequence 题解: 可以通过观察得到,对于任意一个区间来说, 只有相邻的2个点的差值才会是区间的最大值. 具体观察方法,可以用数学分析, 我是通过画图得到的. 那么基于上面的观 ...
- codeforces 572 D. Minimization(dp+ 思维)
题目链接:http://codeforces.com/contest/572/problem/D 题意:给出一个序列,可以任意调整序列的顺序,使得给出的式子的值最小 题解:显然要先排一下序,然后取相邻 ...
- Java服务器-Disruptor使用注意
最近看了一下部署游戏后台的服务器状况,发现我的一个Java程序其占用的CPU时长超过100%,排查后发现竟是Disruptor引起的,让我们来看看究竟为什么Disruptor会有这样的表现. 发现占用 ...
- 【Redis】基本数据类型
一.概述 二.String(字符串) 三.List(列表) 四.Hash(字典) 五.Set(集合) 六.Sorted Set(有序集合) 一.概述 Redis目前支持5种数据类型,分别是: Stri ...
- 《Ansible自动化运维:技术与佳实践》第二章读书笔记
Ansible 安装与配置 本章主要讲的是 Ansible 安装与基本配置,主要包含以下内容: Ansible 环境准备 安装 Ansible 配置运行环境 Ansible 环境准备 从 GitHub ...