前端渲染大量数据思路【虚拟列表】【异步机制】
当浏览器遇到性能瓶颈导致页面卡顿时,你会怎么处理?如何查找问题的原因?
浏览器本身自带性能检测工具,通常我们分析由脚本导致的页面卡顿会选择 性能(performance)
选项卡,在其中我们可以找到导致页面卡顿的函数,另外通过观察我们可以看到脚本的执行时间占比以及页面卡顿的程度。
此外还有 内存
选项卡,可以截取当前页面的内存快照,由于我们的页面通常不像服务器那样一直运行,所以平常我们也不会过于关注页面的内存使用问题。
1. 渲染大量数据
由于要渲染大量数据,我们刚开始学习前端时,如果经验不足就会简单地将所有数据全部一次性地渲染到页面上,这样势必会造成页面的卡顿。所以这种方法我这里也不会去介绍。
下面直接进入正轨,首先提出一个问题引发思考:如果让你去实现,你会怎么实现?
1.1. 采用异步
我首先是想到如果要渲染大量数据,我们可以将这一个巨大的任务拆分成一个个的小任务来执行,将这一个个的小任务加入到任务队列当中采用异步的方式来慢慢地执行。
不过这个会有个缺陷,由于这么多数据是按照顺序来依次执行的,所以当用户想查看比较靠后的数据时,用户会发现数据一直在加载中、一直在渲染,然后用户等啊等,最后点击关闭标签页。
下面是一个简单的使用异步实现的逻辑(只包含部分代码):
const ul = document.querySelector('ul');let total = 100_000_000;
let count = 0;function loop() {const fragment = document.createDocumentFragment();for (let i = 0; i < 20 && count < total; i++, count++) {const li = document.createElement("li");li.textContent = count;fragment.appendChild(li);}ul.appendChild(fragment);window.requestAnimationFrame(loop);
}loop();
观察上面的代码,其中使用到了 requestAnimationFrame
函数,它接收一个函数作为参数,这个函数会在浏览器每一帧渲染结束之后执行。
为什么不使用 setTimeout
定时器,因为 setTimeout 函数无法控制函数的执行时机,我们只知道函数会被加入到任务队列,但并不知道函数会在何时执行,而 requestAnimationFrame 函数则固定在每一帧渲染之后执行,这样就不会在视觉上让用户感觉页面卡顿。
当然如果 requestAnimationFrame 的函数执行时间过长,会推迟下一帧的渲染,所以尽量不要将耗时任务放在其中。
1.2. 虚拟列表
虚拟列表采用的思想类似于懒加载,都是只加载用户看得见的数据,懒加载在计算机上随处可见,比如单例模式中的饿汉式、图片的懒加载等,在我们常用的 QQ 中,像消息列表,联系人列表他也采用了类似于虚拟列表的形式进行渲染,以减少内存的使用量。
因为这里我们要处理大量数据的渲染,如果要求所有的数据必须全部渲染在可视区当中,那么懒加载就派不上用场了。
虚拟列表主要由可视区的数据构成,其他的位置都是空白。我们可以通过 padding 或者是 top/left 来制造空白。如下图所示(图片来自这篇文章 面试官:如何一次性渲染十万条数据 - 掘金 (juejin.cn)),可视区展示我们想看见的数据,缓存区就是我说的空白。
实现的代码如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin: 0;padding: 0;}.scroll-box {height: 100vh;overflow-y: scroll;}</style>
</head>
<body><div class="scroll-box"><ul></ul></div><script src="./test.js"></script>
</body>
</html>
对应的 test.js:
const ul = document.querySelector('ul');
const scrollBox = document.querySelector('.scroll-box');let total = 100_000_000;
let count = 0;
let liHeight = 20;
// 要展示的数据量
let showCount = scrollBox.clientHeight / liHeight >> 0;let totalHeight = total * liHeight;function generateLi() {// 计算出来的处于可视区顶部的数据索引let index = (scrollBox.scrollTop / liHeight) >> 0;const fragment = document.createDocumentFragment();// 制造空白ul.style.paddingTop = `${index * liHeight}px`;ul.style.paddingBottom = `${(totalHeight - (index + 20) * liHeight)}px`;// 生成可视区数据for (let i = 0; i < showCount; i++) {const li = document.createElement("li");li.textContent = `${index + i}`;fragment.appendChild(li);}// 重新设置元素,这里元素并没有考虑复用ul.innerHTML = "";ul.appendChild(fragment);
}generateLi();scrollBox.addEventListener("scroll", generateLi);
多嘴一句,当前元素可以滚动才有 scrollTop 值,否则一直为 0。比如当前元素固定了高度,但是它的子元素的高度超出了它的高度,就会导致溢出,这是我们可以设置 overflow-y: auto
,当前元素就会有滚动条。
而 scrollTop 就是当前元素的顶部与它的子元素的顶部的距离,没有负值。
2. 参考
参考文献:
- 面试官:如何一次性渲染十万条数据 - 掘金 (juejin.cn)
相关文章:
前端渲染大量数据思路【虚拟列表】【异步机制】
当浏览器遇到性能瓶颈导致页面卡顿时,你会怎么处理?如何查找问题的原因? 浏览器本身自带性能检测工具,通常我们分析由脚本导致的页面卡顿会选择 性能(performance) 选项卡,在其中我们可以找到导…...
Ubuntu24.04记录网易邮箱大师的安装
邮箱大师下载 官网自行下载,下载后文件名“mail.deb" https://dashi.163.com/ 安装发现缺少依赖 #mermaid-svg-8wqpqFSBVOPD7NGP {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-8wqpqFSBVOPD7NGP …...
PDF编辑与转换的终极工具智能PDF处理Acrobat Pro DC
Acrobat Pro DC 2023是一款功能全面的PDF编辑管理软件,支持创建、编辑、转换、签署和共享PDF文件。它具备OCR技术,可将扫描文档转换为可编辑文本,同时提供智能PDF处理技术,确保文件完整性和可读性。此外,软件还支持电子…...
Django UpdateView视图
UpdateView是Django中的一个通用视图,用于处理对象的更新操作。它允许用户更新一个已经存在的对象。UpdateView通常与一个模型表单一起使用,这样用户就可以看到当前对象的值,并可以修改它们。 1,添加视图 Test/app3/views.py fr…...
【CS.SE】2024年,你应该选择计算机专业吗?详细分析与未来展望
文章目录 1. 引言1.1 背景介绍 2. 计算机相关专业的现状与挑战2. 计算机相关专业的现状与挑战2.1 行业内的就业趋势2.1.1 现有就业数据2.1.2 行业需求变化 2.2 市场饱和度与竞争2.2.1 毕业生数量增长2.2.2 薪资与职业发展 2.3 技术创新与行业发展2.3.1 新兴技术的发展2.3.2 全球…...
后端开发面经系列 -- 华为OD -- C++面经(全)
华为OD – C面经(全) 公众号:阿Q技术站 文章目录 华为OD -- C面经(全)一面1、C结构体和类的区别,类默认的访问权限,结构体可以定义成员函数吗?2、多态的意义?多态的意义…...
3072. 将元素分配到两个数组中 II Rust 线段树 + 离散化
题目 给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 现定义函数 greaterCount ,使得 greaterCount(arr, val) 返回数组 arr 中 严格大于 val 的元素数量。 你需要使用 n 次操作,将 nums 的所有元素分配到两个数组 arr1 和 arr2 中。在第一次操…...
day35|1005.K次取反后最大化的数组和 134. 加油站135. 分发糖果
文章目录 python语法记录 sort格式 1005.K次取反后最大化的数组和思路方法一方法二 按照绝对值排序 教程🎈✨ 背住 按照绝对值进行降序排序的语法是: 134. 加油站思路方法一 教程解法方法二 暴力求解 135. 分发糖果思路方法一 总结 python语法记录 sort …...
HWA和BSS区别
芯片中的HWA(Hardware Accelerator)模块功能主要是为了加速雷达信号处理的特定任务。HWA模块在雷达系统中起到关键作用,以下是其主要功能和作用: 信号预处理: 滤波:对接收到的雷达信号进行滤波,…...
【Excel】Excel中将日期格式转换为文本格式,并按日期显示。
【问题需求】 在使用excel进行数据导入的过程中, 有的软件要求日期列必须是文本格式。 但是直接将日期列的格式改为文本后,显示一串数字,而不按日期显示。 进而无法导入使用。 【解决方法】 使用【TXET】函数公式进行处理, 在单…...
物联网学习小记
https://www.cnblogs.com/senior-engineer/p/10045658.html GOSP: 提供类似Qt的API接口,仅需要几百KB的硬件资源(比Qt小的多),能运行在Qt不支持的低配置硬件上(对Qt生态形成补充),适用于嵌入式…...
代码随想录-Day29
491. 非递减子序列 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情…...
C/C++ 进阶(6)红黑树
个人主页:仍有未知等待探索-CSDN博客 专题分栏:C 目录 一、概念 性质 二、操作 插入 情况一:cur为红、p为红、g为黑,如果u存在且为红 步骤: 情况二:cur为红、p为红、g为黑,如果u不存在或…...
【Vue】构建vuex-cart模块
说明:既然明确数据要存 vuex,建议分模块存,购物车数据存 cart 模块,将来还会有 user 模块,article 模块… 新建 store/modules/cart.js 挂载到 vuex 仓库上 store/cart.js import Vue from vue import Vuex from vu…...
如何成为嵌入式系统工程师?
各位朋友,如果你们有意向投身于嵌入式开发领域,那么强烈建议你们在软件和硬件两个方面均展开深入且全面的学习。 嵌入式计算机作为嵌入式系统的核心技术支撑,其是直接面向用户、产品以及应用的,无论是软件还是硬件方面都能发挥重要…...
【AI大模型】Transformers大模型库(七):单机多卡推理之device_map
目录 一、引言 二、单机多卡推理之device_map 2.1 概述 2.2 自动配置,如device_map"auto" 2.3 手动配置,如device_map"cuda:1" 三、总结 一、引言 这里的Transformers指的是huggingface开发的大模型库&#x…...
驱动代码编写(一)
驱动程序的作用 驱动程序是指与硬件设备和操作系统进行通信的软件。它的主要功能有以下几个方面: 提供硬件支持:驱动程序允许操作系统与硬件设备进行通信,以便正确地操作和控制硬件设备。它可以向操作系统提供有关硬件设备的各种信息&#x…...
Prompt-to-Prompt Image Editing with Cross Attention Control
Prompt-to-Prompt Image Editing with Cross Attention Control (P2P) Amir Hertz, Tel Aviv University, ICLR23, Paper, Code 1. 前言 编辑对这些生成模型来说是具有挑战性的,因为编辑技术的一个固有特性是保留大部分原始图像,而在基于文本的模型中…...
实验11 OSPF协议配置
实验11 OSPF协议配置 一、OSPF单区域配置(一)原理描述(二)实验目的(三)实验内容(四)实验配置(五)实验步骤 二、OSPF多区域配置(一)原理…...
ChatGPT-4o, 腾讯元宝,通义千问对比测试中文文化
国内的大模型应用我选择了国内综合实力最强的两个,一个是腾讯元宝,一个是通义千问。其它的豆包,Kimi,文心一言等在某些领域也有强于竞品的表现。 问一个中文文化比较基础的问题,我满以为中文文化chatGPT不如国内的大模型。可事实…...
node.js学习
node.js学习实操及笔记 温故node.js,node.js学习实操过程及笔记~ node.js学习视频node.js官网node.js中文网实操笔记githubcsdn笔记 为什么学node.js 可以让别人访问我们编写的网页为后续的框架学习打下基础,三大框架vue react angular离不开node.js …...
python将一个图片雕刻镂空成二维码
本文使用创作助手。 要将一个图片雕刻镂空成二维码,你可以使用Python中的Pillow库来处理图像,并使用qrcode库来生成二维码。以下是一个示例代码,用于将图片雕刻镂空成二维码: import qrcode from PIL import Image# 打开待处理的…...
OS进程取样器OS Process Sampler执行CMD/Shell命令
Apache JMeter - Users Manual: Component Reference 1.背景 项目上最近需要测试一种很少用到的DICOM协议,但是网上资料很少,基本上可以总结为三种方案: 直接发送TCP 16进制数据包,但是参数化数据准备难度大通过开发封装jar包发送,需要开发组提供通过发送cmd命令给前置机…...
excel两个数据表格,怎样实现筛选的联动?
如图,想要通过处理器或者像素条件进行筛选,形成一个右边图2的对比表,如何实现实现联动显示呢? 这个在excel里可以借用数据透视表切片器来完成。步骤如下: 1.添加表 选中数据区域中任意一个单元格,点击 插…...
python,django好的get和post请求
获得get请求 df request.GET.get("dades")获得post请求 文件settings.py关闭csrf MIDDLEWARE [ ‘django.middleware.security.SecurityMiddleware’, ‘django.contrib.sessions.middleware.SessionMiddleware’, ‘django.middleware.common.CommonMiddleware’…...
volatile的用法
目录 前言 使用volatile的注意事项: 示例: 总结: 前言 在嵌入式C编程中,volatile是一个关键字,它用于告知编译器被修饰的变量可能会在程序的任何地方、任何时候被不可预见的、非程序本身控制的因素所改变。这通常…...
MySQL 与 PostgreSQL 关键对比二(SQL语法)
目录 1 详细示例 1.1自动增量列 1.2 字符串连接 1.3 JSON 支持 2 总结 MySQL 和 PostgreSQL 是两种流行的开源关系数据库管理系统(RDBMS)。尽管它们在许多方面相似,但在 SQL 语法和功能上存在一些显著差异。 以下SQL语句的执行如果需要开…...
徐州服务器租用该如何维护?
服务器能够帮助企业处理网络上大部分的数据和信息,在互联网行业中起着十分重要的作用,服务器的存在能够保障网站稳定的运行,主要是由内存、硬盘和处理器等组成,服务器除了进行正常的工作运行,还需要定期维护和管理&…...
C++习题精选(4)—— 栈
目录 1. 最小栈2. 栈的压入弹出序列3. 逆波兰表达式求值 1. 最小栈 题目描述:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素…...
Web前端ES6-ES13笔记合集(下)
#### 五.ES10新特性 ##### 1. Object.fromEntries > Object.fromEntries()方法允许你轻松地将键值对列表转换为对象 js const arr [["name", "kerwin"], ["age", 100]]; console.log(Object.fromEntries(arr))//{name: kerwin, age: 100} …...
北京朝阳区房价2022最新价格/app优化建议
POI框架使用了一段时间,总结下自己的使用经验。 POI框架介绍 Apache POI是Apache软件基金会的开放源码程序库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 1. 07版excel行的上限 2的20次方,超过这个值会报错 2. 下拉列…...
做网站找个人还是找公司/品牌推广和营销推广
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#定义一个密码,列表属性,可以修改password_list [reset, 12345]#定义一个函数,设定输入次数def user_login():tries 3#输入密码while tries > 0 :password input(请输入密码:)#定义密码正确…...
湖北金扬建设网站/怎么建立网站卖东西
2019独角兽企业重金招聘Python工程师标准>>> 开发小结: 转载于:https://my.oschina.net/inchlifc/blog/1609084...
网站建设与管理卷子/网站优化排名方法
这篇文档所给出的编码约定适用于在主要的Python发布版本中组成标准库的Python 代码,请查阅相关的关于在Python的C实现中C代码风格指南的描述。 这篇文档改编自Guido最初的《Python风格指南》一文,并从《Barrys style guide》中添加了部分内容。在有冲突的…...
wordpress 大不开/关键词长尾词优化
DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。 屡获大奖的软件开发平台DevExpress 2022年第一个重要版本——v22.1已正式发布,该版…...
网站内容方案/业务推广网站
题目描述 有些数可以表示成若干个不同阶乘的和。例如,91!2!3!。小明对这些数很感兴趣,所以他给你一个正整数n,想让你告诉他这个数是否可以表示成若干个不同阶乘的和。 输入 输入包含多组测试数据。每组输入…...