09-使用JavaScript处理长列表数据:惰性渲染、虚拟滚动与分批渲染

使用JavaScript处理长列表数据:惰性渲染、虚拟滚动与分批渲染

笔记+分享
在前端开发中,处理长列表数据是一项常见且具有挑战性的任务。为了提升性能和用户体验,开发者可以采用多种技术和方法来优化渲染过程。本文将介绍如何使用原生JavaScript实现惰性渲染、虚拟滚动以及分批渲染。

惰性渲染(Lazy Rendering)

惰性渲染是一种按需加载数据的方法,即只在需要时才渲染页面上的数据。这种方法可以显著减少初始加载时间,提升页面性能。实现惰性渲染的常见方式是使用Intersection Observer API来检测元素是否进入视口。

const lazyLoad = () => {const options = {root: null, // 默认为视口rootMargin: '0px',threshold: 0.1 // 10%的内容进入视口时触发};const observer = new IntersectionObserver((entries, observer) => {entries.forEach(entry => {if (entry.isIntersecting) {const target = entry.target;// 模拟数据加载target.textContent = 'Loaded';observer.unobserve(target); // 加载完成后取消观察}});}, options);document.querySelectorAll('.lazy').forEach(item => {observer.observe(item);});
};document.addEventListener('DOMContentLoaded', lazyLoad);

虚拟滚动(Virtual Scrolling)

虚拟滚动是一种只渲染当前视口内数据的方法,对于长列表数据特别有效。它通过只保留当前视口内的数据,来降低DOM节点数量,从而提升渲染性能。实现虚拟滚动的方式有很多,下面是一个简单的实现示例。

<div id="container" style="height: 500px; overflow-y: auto;"><div id="content" style="height: 20000px; position: relative;"></div>
</div><script>
const container = document.getElementById('container');
const content = document.getElementById('content');
const itemHeight = 20; // 假设每个项的高度为20pxconst renderItems = () => {const scrollTop = container.scrollTop;const viewportHeight = container.clientHeight;const startIdx = Math.floor(scrollTop / itemHeight);const endIdx = Math.floor((scrollTop + viewportHeight) / itemHeight);content.innerHTML = ''; // 清空之前的内容for (let i = startIdx; i <= endIdx; i++) {const item = document.createElement('div');item.style.height = `${itemHeight}px`;item.style.position = 'absolute';item.style.top = `${i * itemHeight}px`;item.textContent = `Item ${i}`;content.appendChild(item);}
};container.addEventListener('scroll', renderItems);
renderItems(); // 初始化渲染
</script>

分批渲染(Batch Rendering)

当数据量较大时,一次性渲染所有数据可能会导致页面卡顿。分批渲染是一种将渲染任务分割成多个小批次的方法,逐步将数据渲染到页面上。我们可以使用 requestAnimationFramesetTimeout 来实现分批渲染。

使用 requestAnimationFrame 进行分批渲染

requestAnimationFrame 是一种告诉浏览器你希望执行动画的一个特定函数,并在重绘之前调用该函数的方法。

const items = new Array(10000).fill(0).map((_, index) => `Item ${index}`);
const container = document.getElementById('container');const renderBatch = (start, end) => {for (let i = start; i < end; i++) {const item = document.createElement('div');item.textContent = items[i];container.appendChild(item);}
};const batchRender = (batchSize = 100) => {let index = 0;const total = items.length;const render = () => {if (index < total) {const end = Math.min(index + batchSize, total);renderBatch(index, end);index = end;requestAnimationFrame(render);}};requestAnimationFrame(render);
};document.addEventListener('DOMContentLoaded', () => {batchRender();
});
使用 setTimeout 进行分批渲染

setTimeout 是一种用于延迟执行代码片段的方法,我们可以利用它将渲染任务分割成多个小批次。

const items = new Array(10000).fill(0).map((_, index) => `Item ${index}`);
const container = document.getElementById('container');const renderBatch = (start, end) => {for (let i = start; i < end; i++) {const item = document.createElement('div');item.textContent = items[i];container.appendChild(item);}
};const batchRender = (batchSize = 100, delay = 0) => {let index = 0;const total = items.length;const render = () => {if (index < total) {const end = Math.min(index + batchSize, total);renderBatch(index, end);index = end;setTimeout(render, delay);}};render();
};document.addEventListener('DOMContentLoaded', () => {batchRender();
});

总结

通过惰性渲染、虚拟滚动以及分批渲染,开发者可以显著优化长列表数据的处理,提升页面性能和用户体验。惰性渲染减少了不必要的数据加载,虚拟滚动仅保留视口内的数据,而分批渲染则避免了一次性渲染大量数据所导致的卡顿。希望本文能帮助你更好地理解和应用这些技术。

参考文档

  • MDN Web Docs - Intersection Observer API
  • MDN Web Docs - requestAnimationFrame
  • MDN Web Docs - setTimeout

通过掌握和应用这些技术,你将能够处理和优化长列表数据的渲染,从而提升用户体验。希望你在实际项目中能够尝试这些方法,享受更加流畅的前端开发体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847336.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库课程设计mysql

数据库课程设计&#xff1a;MySQL 一、引言 数据库设计是数据库技术的一个重要方面&#xff0c;它涉及到数据的组织、存储、检索和管理。MySQL作为目前流行的关系数据库管理系统之一&#xff0c;广泛应用于各种应用场景中。本课程设计旨在通过MySQL平台&#xff0c;让学生深入…

深入探讨Qt中的容器类:QList与QVector

深入探讨Qt中的容器类&#xff1a;QList与QVector 在C的Qt框架中&#xff0c;容器类的选择对性能和内存使用有着重要影响。QList和QVector是Qt中两个常用的容器类&#xff0c;它们虽然在某些方面非常相似&#xff0c;但在实现细节和适用场景上存在显著差异。本文将详细介绍这两…

【Zero to One系列】SpringCloud Gateway结合Nacos完成微服务的网关路由

前期回顾&#xff1a; 【Zero to One系列】springcloud微服务集成nacos&#xff0c;形成分布式系统 1、Gateway依赖配置 主要Maven依赖如下&#xff1a; <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>…

oracle date类型如何比较时间

在 Oracle 数据库中&#xff0c;如果你想要比较 DATE 类型的时间部分&#xff0c;你需要意识到 DATE 类型实际上包含日期和时间信息&#xff0c;精确到秒。但是&#xff0c;由于 DATE 类型没有单独的时间组件&#xff0c;你通常需要一些额外的逻辑来提取或比较时间部分。 以下…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《考虑发用电相似性的海上风电中长期双边协商交易优化决策模》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

小鸡庄园智慧农场养殖游戏开发:科技与农业的完美结合

随着科技的进步&#xff0c;一种全新的游戏模式——智慧农场养殖游戏&#xff0c;正在逐渐崭露头角。本文将深入探讨小鸡庄园智慧农场养殖游戏的开发背景、特点、技术实现方式以及未来的发展趋势&#xff0c;以期为游戏产业创新和农业现代化提供新的思路和启示。 一、开发背景…

Rust 性能分析

都说Rust性能好,但是也得代码写得好,猜猜下面两个代码哪个快 . - 力扣&#xff08;LeetCode&#xff09; use std::collections::HashMap; use lazy_static::lazy_static;lazy_static! {static ref DIGIT: HashMap<char, usize> {let mut m HashMap::new();for c in …

【Nacos】docker-compose启动nacos v2.2.3,启动时修改默认密码不使用naocs

1. 背景 出于安全考虑&#xff0c;我司DevOps平台自动部署的容器化nacos密码不能是弱密码或默认值 但是nacos-v2.2.3官方镜像启动后会初始化nacos用户密码为nacos&#xff0c;修改启动时的变量并没有生效。 2. 部署验证 2.1 yml文件如下 注意将derby库的初始化文件挂载出来…

探索Linux中的fdisk命令:磁盘分区管理的利器

探索Linux中的fdisk命令&#xff1a;磁盘分区管理的利器 在Linux系统管理中&#xff0c;磁盘分区是一项非常重要的任务。它涉及到数据的存储、备份和恢复&#xff0c;以及系统的性能和稳定性。而fdisk&#xff0c;作为Linux下的一款经典磁盘分区工具&#xff0c;凭借其强大的功…

软件测试学习总结-侧开之路的起点

软件测试学习总结-侧开之路的起点 文章目录 一、软件测试的基础理论知识 1、软件测试初了解 2、阅读和梳理需求⽂档 3、测试用例编写 4、缺陷管理 二、Linux系统学习 1、Linux系统学习 三、MySQL数据库学习 1、MySQL数据库学习 四、MySQL数据库学习 1、MySQL数据库学习 …

Python | Leetcode Python题解之第129题求根节点到叶节点数字之和

题目&#xff1a; 题解&#xff1a; class Solution:def sumNumbers(self, root: TreeNode) -> int:if not root:return 0total 0nodeQueue collections.deque([root])numQueue collections.deque([root.val])while nodeQueue:node nodeQueue.popleft()num numQueue.p…

产品人生(9):从“波士顿矩阵”看“个人职业规划”

波士顿矩阵&#xff08;简称BCG矩阵&#xff09;是一种战略规划工具&#xff0c;由波士顿咨询公司的创始人布鲁斯亨德森&#xff08;Bruce Henderson&#xff09;于1970年代初提出的&#xff0c;它以两个关键指标作为分析维度&#xff1a;市场增长率和相对市场份额&#xff0c;…

探索k8s集群的配置资源(secret和configmap)

目录 ConfigMap ConfigMap&#xff08;主要是将配置目录或者文件挂载到k8s里面使用&#xff09; 与Secret类似&#xff0c;区别在于ConfigMap保存的是不需要加密配置的信息。&#xff08;例如&#xff1a;配置文件&#xff09; ConfigMap 功能在 Kubernetes1.2 版本中引入&…

过期视频怎么恢复?如何从手机、电脑和其他设备中恢复?

过期视频是指那些被误删、丢失或因系统升级等原因而无法正常访问的视频文件。这些视频可能包含了我们珍贵的回忆、重要的信息或者具有商业价值的内容。过期视频的恢复可以帮助我们找回失去的数据&#xff0c;减少损失&#xff0c;提高工作效率和生活质量。过期视频怎么恢复&…

Android WebView上传文件/自定义弹窗技术,附件的解决方案

安卓内核开发 其实是Android的webview默认是不支持<input type"file"/>文件上传的。现在的前端页面需要处理的是&#xff1a; 权限 文件路径AndroidManifest.xml <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…

【AI基础】第二步:安装AI运行环境

开局一张图&#xff1a; 接下来按照从下往上的顺序来安装部署。 规则1 注意每个层级的安装版本&#xff0c;上层的版本由下层版本决定 比如CUDA的版本&#xff0c;需要看显卡安装了什么版本的驱动&#xff0c;然后CUDA的版本不能高于这个驱动的版本。 这个比较好理解&#xff…

毕业论文word常见问题

0、前言&#xff1a; 这里的问题都是以office办公软件当中的word为例&#xff0c;和WPS没有关系。 1、页眉横线删不掉&#xff1a; 解决方案&#xff1a;进入页眉编辑状态&#xff0c;在开始选项栏中选择页眉字体样式&#xff0c;清除格式。 修改方式如下&#xff1a; 2、…

mysql inset bug

在 SQL 中&#xff0c;日期值需要用单引号包围&#xff0c;这是因为 SQL 将日期值视为字符串格式。数据库引擎在处理这些值时会将它们解析为适当的日期类型。如果不使用单引号&#xff0c;数据库引擎会将它们视为数字或列名&#xff0c;从而导致语法错误。 日期格式 MySQL 支…

在Linux/Ubuntu/Debian系统中使用 `tar` 压缩文件

在Linux/Ubuntu/Debian系统中使用 tar 压缩文件 tar 命令是用于在类 Unix 操作系统中创建文件和目录存档的强大实用程序。 基本存档创建 要创建文件夹的简单存档&#xff0c;请使用以下命令&#xff1a; tar -cf ./my-archive.tar ./my-folder/此命令将创建一个名为 my-arc…

java入门 Netty ByteBuf

一、 参考资料 参考黑马netty教程 https://www.bilibili.com/video/BV1py4y1E7oA?p88&spm_id_frompageDriver&vd_source4cd1b6f268e2a29a11bea5d2568836ee 二、 ByteBuf测试 app.java package com.sht.test;import io.netty.buffer.ByteBuf; import io.netty.buff…