前端时间分片渲染
在经典的面试题中:”如果后端返回了十万条数据要你插入到页面中,你会怎么处理?”
除了像 useVirtualList 这样的虚拟列表来处理外,我们还可以通过 时间分片 来处理
通过 setTimeout
直接上一个例子:
<!--* @Author: Jolyne* @Date: 2023-09-22 15:45:45* @LastEditTime: 2023-09-22 15:47:24* @LastEditors: Jolyne* @Description:
-->
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>十万数据渲染</title>
</head><body><ul id="list-container"></ul><script>const oListContainer = document.getElementById('list-container')const fetchData = () => {return new Promise(resolve => {const response = {code: 0,msg: 'success',data: [],}for (let i = 0; i < 100000; i++) {response.data.push(`content-${i + 1}`)}setTimeout(() => {resolve(response)}, 100)})}// 模拟请求后端接口返回十万条数据// 渲染 total 条数据中的第 page 页,每页 pageCount 条数据const renderData = (data, total, page, pageCount) => {// base case -- total 为 0 时没有数据要渲染 不再递归调用if (total <= 0) return// total 比 pageCount 少时只渲染 total 条数据pageCount = Math.min(pageCount, total)setTimeout(() => {const startIdx = page * pageCountconst endIdx = startIdx + pageCountconst dataList = data.slice(startIdx, endIdx)// 将 pageCount 条数据插入到容器中for (let i = 0; i < pageCount; i++) {const oItem = document.createElement('li')oItem.innerText = dataList[i]oListContainer.appendChild(oItem)}renderData(data, total - pageCount, page + 1, pageCount)}, 0)}fetchData().then(res => {renderData(res.data, res.data.length, 0, 200)})</script>
</body></html>
上面的例子中,我们使用了 setTimeout,在每一次宏任务中插入一页数据,然后设置多个这样地宏任务,直到把所有数据都插入为止。
但是很明显能看到的问题是,快速拖动滚动条时,数据列表中会有闪烁的情况
这是因为:
当使用
setTimeout来拆分大量的 DOM 插入操作时,虽然我们将延迟时间设置为 0ms,但实际上由于 JavaScript 是单线程的,任务执行时会被放入到事件队列中,而事件队列中的任务需要等待当前任务执行完成后才能执行。所以即使设置了 0ms 延迟,setTimeout的回调函数也不一定会立即执行,可能会受到其他任务的阻塞。
当
setTimeout的回调函数执行的间隔超过了浏览器每帧更新的时间间隔(一般是 16.7ms),就会出现丢帧现象。丢帧指的是浏览器在更新页面时,没有足够的时间执行全部的任务,导致部分任务被跳过,从而导致页面渲染不连续,出现闪烁的情况
所以,我们改善一下,通过 requestAnimationFrame 来处理
通过 requestAnimationFrame
<!--* @Author: Jolyne* @Date: 2023-09-22 15:45:45* @LastEditTime: 2023-09-22 15:47:24* @LastEditors: Jolyne* @Description:
-->
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>直接插入十万条数据</title>
</head><body><ul id="list-container"></ul><script>const oListContainer = document.getElementById('list-container')const fetchData = () => {return new Promise(resolve => {const response = {code: 0,msg: 'success',data: [],}for (let i = 0; i < 100000; i++) {response.data.push(`content-${i + 1}`)}setTimeout(() => {resolve(response)}, 100)})}// 模拟请求后端接口返回十万条数据// 渲染 total 条数据中的第 page 页,每页 pageCount 条数据const renderData = (data, total, page, pageCount) => {// base case -- total 为 0 时没有数据要渲染 不再递归调用if (total <= 0) return// total 比 pageCount 少时只渲染 total 条数据pageCount = Math.min(pageCount, total)requestAnimationFrame(() => {const startIdx = page * pageCountconst endIdx = startIdx + pageCountconst dataList = data.slice(startIdx, endIdx)// 将 pageCount 条数据插入到容器中for (let i = 0; i < pageCount; i++) {const oItem = document.createElement('li')oItem.innerText = dataList[i]oListContainer.appendChild(oItem)}renderData(data, total - pageCount, page + 1, pageCount)})}fetchData().then(res => {renderData(res.data, res.data.length, 0, 200)})</script>
</body></html>
很明显,闪烁的问题被解决了
这是因为:
requestAnimationFrame会在浏览器每次进行页面渲染时执行回调函数,保证了每次任务的执行间隔是稳定的,避免了丢帧现象。所以在处理大量 DOM 插入操作时,推荐使用requestAnimationFrame来拆分任务,以获得更流畅的渲染效果
相关文章:
前端时间分片渲染
在经典的面试题中:”如果后端返回了十万条数据要你插入到页面中,你会怎么处理?” 除了像 useVirtualList 这样的虚拟列表来处理外,我们还可以通过 时间分片 来处理 通过 setTimeout 直接上一个例子: <!--* Autho…...
亿图导出word和PDF中清晰度保留方法
步骤一 在亿图软件中画一个元件大小搭配合理的图。注意字体大小的安排,尤其是角标的大小要合适,示范如下 选中所有元器件,右键使用组合功能将电路图组合为一个整体 步骤二: 将亿图软件中的图保存为SVG格式。示范如下 在导出到…...
chatGPT结构及商业级相似模型应用调研
GPT前言 说明 ChatGPT这项技术的历史可以追溯到2018年,当时由Facebook实验室的团队开发出该技术,以开发聊天机器人为目的。随后,ChatGPT在2019年由来自谷歌的DeepMind团队在国际会议ICLR上发表了论文,其中提出了ChatGPT的技术框架…...
HarmonyOS鸿蒙原生应用开发设计- 华为分享图标
HarmonyOS设计文档中,为大家提供了独特的华为分享图标,开发者可以根据需要直接引用。 开发者直接使用官方提供的华为分享图标内容,既可以符合HarmonyOS原生应用的开发上架运营规范,又可以防止使用别人的内容产生的侵权意外情况等&…...
Java基础-反射
代理相关 为什么需要代理? 代理可以无侵入式的对方法进行增强,而不需要修改原始方法的代码,这样就可以在不修改原始方法的情况下,对方法进行增强。 代理长什么样子? 代理里面就是对象要被代理的方法 Java通过什么方式…...
计算机毕设 大数据二手房数据爬取与分析可视化 -python 数据分析 可视化
# 1 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通…...
【转载】 Bytedance火山引擎智能拥塞控制算法 VICC
BytedanceTechBlog : 火山引擎实时、低延时拥塞控制算法的优化实践 火山引擎 网站如何利用播放器节省20%点播成本点击下面的链接进入原文:原创 翟强俊、唐辉 字节跳动技术团队 2023-10-18 11:59 发表于北京 一些专利摘要 火山引擎智能拥塞控制算法 VICC(Volcano Intelligent…...
Postman如何测试WebService接口
前言: 由于工作所需,需要使用Postman测试工具,对基于ws规范的WebService接口进行测试.在经过多种尝试后,终于找到了正确的测试方法.下面我便详细记录测试步骤,以便以后再次测试时可以拿来主义. 第一步:确保WebService服务端正常启动(注意服务端各个接口发布的url地址) 第二步…...
微服务-Eureka
文章目录 提供者与消费者Eureka注册中心搭建EurekaServer服务注册服务发现项目结构 提供者与消费者 Eureka注册中心 服务消费者该如何获取服务提供者的地址信息? 服务提供者启动时向eureka注册自己的信息 eureka保存这些信息 消费者根据服务名称向eureka拉取提供者信…...
超声电机工作原理
超声波电机的工作原理 在压电陶瓷振子上加高频交流电压时,利用逆压电效应或电致伸缩效应使定子产生微观机械振动。并将这种振动通过共振放大和摩擦耦合变换成旋转或直线型运动。 超声波驱动有两个前提条件: 需在定子表面激励出稳态的质点椭圆运动轨迹…...
基于人工蜂鸟优化的BP神经网络(分类应用) - 附代码
基于人工蜂鸟优化的BP神经网络(分类应用) - 附代码 文章目录 基于人工蜂鸟优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.人工蜂鸟优化BP神经网络3.1 BP神经网络参数设置3.2 人工蜂鸟算法应用 4.测试结果…...
两个list中存放相同的对象,一个是页面导入,一个是从数据库查询,外部传入一个集合存放的是对象的属性名称,根据属性名称处理两个list
需求:两个list中存放相同的对象,一个是页面导入,一个是从数据库查询,外部传入一个集合存放的是对象的属性名称.要求根据传入的属性(多个)判断两个list中是否有重复的对象, 如果重复则删除数据库的list, 然后合并两个list. /*** 处理导入和数据库重复数据* param list* param l…...
为什么C++能搜到的框架介绍都好抽象?
为什么C能搜到的框架介绍都好抽象? 那是因为c每次都要自建生态 随便一个库发展到一定阶段,它就开始跨界,做得又大又全 结果就是,虽然都叫c,但其实是由一大堆不同生态组成的统称 c跟c的差异,比java跟c的差…...
人工智能(6):机器学习基础环境安装与使用
1 库的安装 整个机器学习基础阶段会用到Matplotlib、Numpy、Pandas等库,为了统一版本号在环境中使用,将所有的库及其版本放到了文件requirements.txt当中,然后统一安装 新建一个用于人工智能环境的虚拟环境 mkvirtualenv ai matplotlib3.8…...
电力巡检/电力抢修行业解决方案:AI+视频技术助力解决巡检监管难题
一、行业背景 随着国民经济的蓬勃发展,工业用电和居民用电需求迅速增加,电厂、变电站、输电线路高负荷运转,一旦某个节点发生故障,对生产、生活造成巨大的影响。目前电力行业生产现场人员、设备较多,而生产监督员有限…...
区块链轻节点的问答
EOS的nodeos并没有获取merkle proof的功能,那应该怎样获取merkle proof nodeos(EOS区块链节点软件)本身并不提供Merkle Proof的功能,而是全节点或其他数据源通常提供Merkle Proof。获取Merkle Proof的过程通常需要与全节点或区块浏…...
常用Web安全扫描工具汇整
漏洞扫描是一种安全检测行为,更是一类重要的网络安全技术,它能够有效提高网络的安全性,而且漏洞扫描属于主动的防范措施,可以很好地避免黑客攻击行为,做到防患于未然。 1、AWVS Acunetix Web Vulnerability Scanner&a…...
查看当前cmake版本支持哪些版本的Visual Studio
不同版本的的cmake对Visual Studio的版本支持不同,以下图示展示了如何查看当前安装的cmake支持哪些版本的Visual Studio。 1.打开cmake-gui 2.查看cmake支持哪些版本的Visual Studio...
岩土工程桥梁监测中智能振弦传感器的应用方案
岩土工程桥梁监测中智能振弦传感器的应用方案 岩土工程桥梁监测是重要的安全保障措施,而智能振弦传感器是其中一种有效的监测手段。它可以通过测量桥梁振动的频率和幅值,监测桥梁的健康状态,预测可能出现的问题,并及时采取措施进…...
上云容灾如何实现碳中和-万博智云受邀参加1024程序员节数据技术论坛并发表演讲
近日,2023长沙中国1024程序员节在长沙召开。 长沙中国1024程序员节继2020年后已成功连续举办三届,逐步成为 IT 行业引领技术前沿、推动应用创新发展的高影响力年度盛会。是 IT 领域新技术、新产品、新服务的重要发布平台。 万博智云CEO Michael受邀参加…...
Python下载指南:x86、amd64、ARM、32位、64位到底怎么选?
Python下载指南:x86、amd64、ARM、32位、64位到底怎么选? 在下载 Python(或其他软件)时,你是否对着满屏的 x86、amd64、ARM64、32-bit、64-bit 感到头大? 别担心,这些术语其实只代表两个核心维度…...
基于深度学习的轴承故障诊断:CNN-LSTM架构演进与核心代码逻辑拆解
基于深度学习的轴承故障诊断:CNN-LSTM架构演进与核心代码逻辑拆解前言 在设备健康管理(PHM)的实战中,面对凯斯西储大学(CWRU)轴承数据集,直接将几十万个采样点的振动信号塞给模型是行不通的。即…...
突破限速!多平台适配的网盘直链下载工具:3步解锁高速下载体验
突破限速!多平台适配的网盘直链下载工具:3步解锁高速下载体验 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中…...
效率提升秘籍:用快马AI自动生成openclaw一键部署与依赖管理脚本
最近在折腾openclaw框架时,发现环境配置真是个效率黑洞。每次在新设备上部署,光是查文档、解决依赖冲突就要花掉大半天。于是琢磨着用自动化工具来优化这个流程,没想到效果出奇的好,今天就把这套方案分享给大家。 环境配置分析器&…...
气象、水文、区域气候--从零搭建 WRF 实验室:Linux 编译 + Python 绘图 + 下垫面改造一站式技术
做气象、水文、气候、环境、地理遥感等领域的科研人,是不是都逃不过这些噩梦:编译地狱:Linux 环境下 NetCDF、MPI、WRF 编译报错满天飞,compile.log里的 Error 看不懂,卡了一周连第一步都跑不通环境混乱:Fo…...
被忽视的性能金矿:如何释放笔记本90%隐藏算力
被忽视的性能金矿:如何释放笔记本90%隐藏算力 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar, and …...
泛微OA字段联动与JS代码顺序控制的实战技巧:如何避免数据遍历中的坑
泛微OA字段联动与JS代码顺序控制的实战技巧:如何避免数据遍历中的坑 在泛微OA系统的二次开发中,字段联动和JS代码控制是提升表单交互性的两大核心功能。但当这两个功能需要在同一业务流程中协同工作时,开发者常常会遇到一个棘手的问题&#x…...
MarkDown语法学习总结
MarkDown语法学习 一级标题:#空格标题名 二级标题 二级标题:##空格标题名 几级标题就写几个# 字体 粗体:** 文本 ** 你好 斜体:* 文本 * 你好 斜体加粗:* * * 文本 * * * 你好 删除线:~~ 文本~…...
如何让你的第三方鼠标在macOS上重获新生?Mac Mouse Fix让普通鼠标体验提升300%
如何让你的第三方鼠标在macOS上重获新生?Mac Mouse Fix让普通鼠标体验提升300% 【免费下载链接】mac-mouse-fix Mac Mouse Fix - Make Your $10 Mouse Better Than an Apple Trackpad! 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 你是…...
Android Photo Picker 避坑指南:从权限管理到低版本兼容的完整方案
Android Photo Picker 避坑指南:从权限管理到低版本兼容的完整方案 在移动应用开发中,图片选择功能几乎是社交、电商类App的标配需求。但就是这个看似简单的功能,却让不少开发者踩过坑:权限申请被用户拒绝、不同Android版本表现不…...
