虚拟列表通过只渲染可视区域数据实现高性能滚动。核心是固定高度容器、phantom占位撑起滚动条、list动态定位;支持js预计算动态高度、滚动监听索引计算、分页增量更新,十万条数据仍流畅。

直接渲染海量接口数据会导致页面卡顿、内存飙升、滚动掉帧。虚拟列表不是“懒加载”,而是“只渲染看得见的那几条”,配合高度占位和动态更新,让十万条数据也能丝滑滚动。
核心结构:容器 + 占位 + 可视区
外层容器必须设固定高度和 overflow-y: auto,形成滚动视口。内部用两个关键部分:
- 一个空的
<div class="phantom">,通过 <code>height设置为总内容高度(比如所有项高度之和),撑起滚动条长度 - 一个
<div class="list">,只放当前可视区域的数据,并用 <code>transform: translateY()精确定位到对应位置动态高度处理:不测 DOM,纯 JS 算
接口数据每条高度不一(比如含多行文本、头像、操作按钮)时,传统方案靠临时插入 DOM 测高,会触发回流,性能差。推荐用 Pretext 这类纯 JS 文本布局库:
Alibabacloud Sdk Client Initialization For Java下载在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 传入文本内容、字体、字号、宽度,直接返回换行后高度
- 首次加载时批量预计算所有项高度,存入数组缓存(
heights[i] = calc(item)) - 后续滚动只需查表累加,无需重复计算
滚动监听与索引计算
监听容器
scroll事件,根据scrollTop动态算出当前该显示哪一段:- 从顶部开始累加缓存的高度,找到第一个 ≥
scrollTop的索引,即为startIndex -
endIndex = startIndex + visibleCount + buffer(buffer 通常取 3~5,防快速滚动白屏) - 可视项数
visibleCount不是固定值,而是Math.ceil(container.clientHeight / avgItemHeight),再结合缓冲更稳妥
数据加载与增量更新
如果接口本身分页(如每次拉 100 条),可无缝接入上拉加载:
- 初始加载第 1 页,同时预计算这 100 条的高度并缓存
- 滚动到底部时请求下一页,追加到原始数据数组末尾,并同步追加新高度到缓存数组
- 总高度实时更新:
totalHeight = heights.reduce((a, b) => a + b, 0) - 无需重绘整个列表,只刷新可视区域即可










