面试(进阶) —虚拟列表在什么场景使用,如何实现?
面试(进阶) —虚拟列表在什么场景使用,如何实现?
在前端开发中,当需要渲染大量数据时,传统的渲染方式往往会遇到性能瓶颈。一次性将大量数据渲染到DOM中,不仅会导致页面加载缓慢,还可能占用大量内存,影响浏览器的响应速度。为了解决这个问题,虚拟列表(Virtual List)技术应运而生。

虚拟列表的定义
虚拟列表是一种优化长列表渲染的技术。它的核心思想是:只渲染当前视口(viewport)内可见的数据项,而非一次性渲染所有数据。通过动态计算视口内应显示的数据项,虚拟列表能够显著减少DOM节点的数量,从而提高页面的渲染性能和交互流畅度。
虚拟列表的关键点
- 视口计算:确定当前视口的大小和位置,以及每个列表项的高度。
- 数据截取:根据视口的位置和大小,从数据源中截取应显示的数据项。
- DOM渲染:仅将截取的数据项渲染到DOM中。
- 滚动监听:监听用户的滚动操作,实时更新视口的位置,并重新渲染可见的数据项。
虚拟列表的实现原理
虚拟列表的实现通常涉及以下几个步骤:
- 计算视口高度和列表项高度:这是为了确定在视口内能够显示多少个列表项。
- 确定起始和结束索引:根据滚动条的位置和列表项的高度,计算出当前视口内应显示的起始和结束数据索引。
- 渲染数据:根据计算出的起始和结束索引,从数据源中截取相应部分的数据进行渲染。
- 更新视口:监听滚动事件,当用户滚动列表时,重新计算起始和结束索引,并更新渲染的内容。
Vue版本案例代码
下面是一个使用Vue.js实现的虚拟列表示例:
<template><div id="app"><div class="container" ref="container" @scroll="handleScroll"><divclass="item"v-for="(item, index) in visibleItems":key="index":style="{ top: `${(startIndex + index) * itemHeight}px` }">{{ item }}</div></div></div>
</template><script>
export default {data() {return {items: [], // 数据源itemHeight: 30, // 每个列表项的高度containerHeight: 300, // 容器高度startIndex: 0, // 当前视口的起始索引endIndex: 0, // 当前视口的结束索引};},computed: {visibleItems() {// 计算当前视口内应显示的数据项return this.items.slice(this.startIndex, this.endIndex);},},mounted() {// 初始化数据源this.items = Array.from({ length: 1000 }, (_, i) => `Item ${i + 1}`);this.updateVisibleItems();},methods: {updateVisibleItems() {// 更新视口内的起始和结束索引const container = this.$refs.container;const totalItems = this.items.length;const displayedItems = Math.ceil(this.containerHeight / this.itemHeight);this.startIndex = Math.max(0, Math.floor(container.scrollTop / this.itemHeight));this.endIndex = Math.min(totalItems, this.startIndex + displayedItems);},handleScroll() {// 监听滚动事件,更新可见数据项this.updateVisibleItems();},},
};
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;text-align: center;color: #2c3e50;margin-top: 60px;
}.container {height: 300px;overflow-y: auto;border: 1px solid #ccc;position: relative;
}.item {height: 30px;border-bottom: 1px solid #eee;padding: 5px;box-sizing: border-box;position: absolute;width: 100%;
}
</style>
解析描述
模板部分
- 使用
<div>元素作为容器,并绑定了滚动事件监听器。 - 使用
v-for指令循环渲染可见的数据项,并通过:style绑定动态设置每个列表项的顶部位置。
脚本部分
- 定义了数据源
items,每个列表项的高度itemHeight,容器高度containerHeight,以及当前视口的起始和结束索引startIndex和endIndex。 - 在
mounted生命周期钩子中初始化数据源,并调用updateVisibleItems方法更新可见数据项。 - 定义了
updateVisibleItems方法,用于根据滚动条的位置更新视口内的起始和结束索引。 - 定义了
handleScroll方法,监听滚动事件并调用updateVisibleItems方法更新可见数据项。
样式部分
- 为容器和列表项设置了样式,包括高度、边框、滚动条等。
- 使用
position: absolute;为列表项设置绝对定位,以便根据起始索引动态调整每个列表项的位置。
通过这个Vue版本的虚拟列表实现,我们可以更加直观地理解虚拟列表的工作原理和实现方式。在实际应用中,还可以根据需要进行进一步优化和扩展,如支持动态调整列表项高度、处理大量数据时的性能优化等。
虚拟列表的优缺点
优点:
- 性能提升:虚拟列表通过只渲染可视区域内的项,显著减少了DOM元素的数量,从而提高了页面的渲染效率和响应速度。这对于处理大量数据(如十万、百万级别)的列表尤其有效。
- 内存优化:由于只渲染可见区域内的元素,虚拟列表节省了内存消耗,避免了大规模数据的全部渲染,有助于提升应用的性能。
- 流畅体验:用户滚动列表时,虚拟列表可以实现流畅的加载和切换,减少了页面卡顿现象,提升了用户体验。
缺点:
- 实现复杂度:虚拟列表的实现相对复杂,需要开发者具备一定的前端技术基础,包括DOM操作、事件监听、计算逻辑等。
- 兼容性:在某些特殊情况下,虚拟列表可能与某些CSS样式或布局方式存在兼容性问题,需要开发者进行额外的调试和优化。
比较
| 列表类型 | 渲染方式 | 优缺点 | 适用场景 |
|---|---|---|---|
| 虚拟列表 | 只渲染可视区域内的项 | 优点:性能高、内存占用少、用户体验流畅;缺点:实现复杂、可能存在兼容性问题 | 处理大量数据的列表,如聊天记录、商品列表、评论区等 |
| 普通列表 | 一次性渲染所有数据项 | 优点:实现简单;缺点:性能低、内存占用高、用户体验可能卡顿 | 数据量较小的列表,如导航菜单、标签页等 |
| 分页列表 | 分批次加载数据并渲染 | 优点:减少单次加载的数据量,提升性能;缺点:用户需要手动翻页,体验可能不如虚拟列表流畅 | 数据量较大的列表,且希望减少单次加载压力的情况 |
| 无限滚动列表 | 用户滚动到底部时加载更多数据 | 优点:用户体验较为流畅,无需手动翻页;缺点:可能存在性能问题,尤其是在数据量非常大的情况下 | 希望提供连续滚动体验的场景,如新闻资讯、社交媒体等 |
分析:
- 普通列表适用于数据量较小的场景,实现简单但性能较低。
- 分页列表通过分批次加载数据来减少单次加载的压力,适用于数据量较大的情况,但用户需要手动翻页,体验可能不如虚拟列表流畅。
- 无限滚动列表提供了连续滚动的体验,适用于希望用户能够连续浏览的场景,但在数据量非常大的情况下可能存在性能问题。
- 虚拟列表则通过只渲染可视区域内的项来显著提升性能和用户体验,特别适用于处理大量数据的列表场景。然而,其实现相对复杂,且可能存在兼容性问题。
在选择列表类型时,开发者应根据具体的应用场景、数据量、性能要求以及用户体验需求进行综合考虑。
看到这里的小伙伴,欢迎点赞、评论,收藏!
如有前端相关疑问,博主会在第一时间解答,也同样欢迎添加博主好友,共同进步!!!

相关文章:
面试(进阶) —虚拟列表在什么场景使用,如何实现?
面试(进阶) —虚拟列表在什么场景使用,如何实现? 在前端开发中,当需要渲染大量数据时,传统的渲染方式往往会遇到性能瓶颈。一次性将大量数据渲染到DOM中,不仅会导致页面加载缓慢,还可能占用大量内存&#x…...
深入了解 NAT 模式:网络地址转换的奥秘
深入了解 NAT 模式:网络地址转换的奥秘 在计算机网络的世界里,NAT 模式(Network Address Translation,网络地址转换)扮演着至关重要的角色。它就像是网络中的翻译官,在不同网络地址之间进行转换࿰…...
Android Studio 新版本Gradle发布本地Maven仓库示例
发布代码到JitPack示例:https://blog.csdn.net/loutengyuan/article/details/145938967 以下是基于 Android Studio 24.2.2(Gradle 8.10.2 AGP 8.8.0 JDK17) 的本地 Maven 仓库发布示例,包含aar和jar的不同配置: 1.…...
无服务边缘融合架构:重新定义云原生应用边界
引言:零部署计算的革命突破 Airbnb迁移至LambdaEdge架构后,全球客房详情页渲染延迟降至35ms,冷启动时间缩至50ms以内。Stripe采用无服务边缘计算处理支付事务,成功将动态API响应P99延迟从210ms压缩至19ms。AWS官方基准显示&#…...
数据库测试
TPCH 22条SQL语句分析 - xibuhaohao - 博客园 TPCH模型规范、测试说明及22条语句 - zhjh256 - 博客园 TPC-DS 性能比较:TiDB 与 Impala-PingCAP | 平凯星辰 揭秘Oracle TPC-H性能优化:如何提升数据库查询速度,揭秘实战技巧与挑战 引言 T…...
Nodejs-逐行读取文件【简易版】
“勤奋就是成功之母。” —— 茅以升 目录 逐行读取文件四种方法:Node.js 逐行读取文件的核心方法:同步读取(适用于小文件):异步流式处理(推荐用于大文件):[使用 readline 模块](h…...
上海市计算机学会竞赛平台2024年5月月赛丙组城市距离之和
城市距离之和 内存限制: 256 Mb时间限制: 1000 ms 题目描述 设 (x,y)(x,y) 与 (x′,y′)(x′,y′) 是平面上的两个点的坐标,它们之间的城市距离定义为 ∣x−x′∣∣y−y′∣∣x−x′∣∣y−y′∣ 给定 nn 个点,请计算所有点对之间的城市距离之和。 …...
穷举vs暴搜vs深搜vs回溯vs剪枝(典型算法思想)—— OJ例题算法解析思路
回溯算法的模版 void backtrack(vector<int>& path, vector<int>& choice, ...) {// 满⾜结束条件if (/* 满⾜结束条件 */) {// 将路径添加到结果集中res.push_back(path);return;}// 遍历所有选择for (int i 0; i < choices.size(); i) {// 做出选择…...
在ubuntu 24.04.2 通过 Kubeadm 安装 Kubernetes v1.31.6
文章目录 1. 简介2. 准备3. 配置 containerd4. kubeadm 安装集群5. 安装网络 calico 插件 1. 简介 本指南介绍了如何在 Ubuntu 24.04.2 LTS 上安装和配置 Kubernetes 1.31.6 集群,包括容器运行时 containerd 的安装与配置,以及使用 kubeadm 进行集群初始…...
基于Python socket库构建的基于 P2P 的文件共享系统示例
基于 P2P 的文件共享系统 实现方式: 使用 Python 的socket库构建 P2P 网络,节点之间通过 TCP 或 UDP 协议进行通信。每个节点维护一个文件列表,并向其他节点广播自己拥有的文件信息。当一个节点需要某个文件时,它会向网络中的其…...
JavaScript 函数重载:灵活应对多场景的编程技巧
在 JavaScript 中,函数重载(Function Overloading)是一个常见的需求。尽管 JavaScript 本身并不支持传统意义上的函数重载(即在同一个作用域内定义多个同名函数,根据参数的不同调用不同的函数),…...
通过 PromptTemplate 生成干净的 SQL 查询语句并执行SQL查询语句
问题描述 在使用 LangChain 和 Llama 模型生成 SQL 查询时,遇到了 sqlite3.OperationalError 错误。错误信息如下: OperationalError: (sqlite3.OperationalError) near "sql SELECT Name FROM MediaType LIMIT 5; ": syntax error [SQL: …...
用大白话解释缓存Redis +MongoDB是什么有什么用怎么用
Redis和MongoDB是什么? Redis:像你家的“小冰箱”,专门存高频使用的食物(数据)。它是基于内存的键值数据库,读写速度极快(每秒超10万次操作)。比如你每次打开手机App,用…...
计算机毕业设计SpringBoot+Vue.js汽车销售网站(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
【0010】HTML水平线标签详解
如果你觉得我的文章写的不错,请关注我哟,请点赞、评论,收藏此文章,谢谢! 本文内容体系结构如下: 一、水平线标签概述 在HTML中,<hr>标签用于在网页上插入一条水平线,其主要…...
FastExcel与Reactor响应式编程深度集成技术解析
一、技术融合背景与核心价值 在2025年企业级应用开发中,大规模异步Excel处理与响应式系统架构的结合已成为技术刚需。FastExcel与Reactor的整合方案,通过以下技术协同实现突破性性能: 内存效率革命:FastExcel的流式字节操作与Re…...
Netty是如何实现零拷贝的?
大家好,我是锋哥。今天分享关于【Netty是如何实现零拷贝的?】面试题。希望对大家有帮助; Netty是如何实现零拷贝的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Netty是一个高性能的Java网络应用框架,它…...
【大模型➕知识图谱】大模型结合医疗知识图谱:解锁智能辅助诊疗系统新范式
【大模型➕知识图谱】大模型结合医疗知识图谱:解锁智能辅助诊疗系统新范式 大模型结合医疗知识图谱:解锁智能辅助诊疗系统新范式引言一、系统架构1.1 系统架构图1.2 架构模块说明1.2.1 用户输入1.2.2 大模型(语义理解与意图识别)1.2.3 Agent(问题解析与任务分配)1.2.4 问…...
Spring Boot @Component注解介绍
Component 是 Spring 中的一个核心注解,用于声明一个类为 Spring 管理的组件(Bean)。它是一个通用的注解,可以用于任何层次的类(如服务层、控制器层、持久层等)。通过 Component 注解,Spring 会…...
MulFS-CAP: Multimodal Fusion-supervisedCross-modal
一种用于无注册红外-可见图像融合的单阶段框架。与传统的两阶段方法不同,MulFS-CAP结合了隐式注册和融合,简化了处理流程并增强了实用性。该方法使用共享的浅层特征编码器,同时进行特征对齐和图像融合。通过引入可学习的模态字典,…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
