news 2026/5/7 2:49:49

前端如何虚拟列表优化?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
前端如何虚拟列表优化?

一、为什么要用虚拟列表?

问题本质

当列表数据很多时(如 1w+):

  • DOM 数量过多 →重排 / 重绘严重

  • 滚动卡顿

  • React diff 变慢

  • 表格(Antd Table)尤其明显

👉瓶颈不在 JS,而在 DOM


二、虚拟列表核心原理(一句话版)

只渲染“可视区域 + 上下缓冲”的那一小段数据,其它用空白高度“占位”

关键点只有 4 个:

  1. 滚动容器高度固定

  2. 每一项高度固定 or 可计算

  3. 根据 scrollTop 计算 startIndex / endIndex

  4. 用 translateY 或 padding-top 做偏移


三、基础实现原理(固定高度版)

1️⃣ 核心计算公式

const itemHeight = 40 const containerHeight = 400 const visibleCount = Math.ceil(containerHeight / itemHeight) const startIndex = Math.floor(scrollTop / itemHeight) const endIndex = startIndex + visibleCount + buffer

2️⃣ DOM 结构示意

<div class="container" onScroll> <div style="height: totalHeight"> <div style="transform: translateY(offset)"> {visibleItems.map(render)} </div> </div> </div>

3️⃣ React 简化示例

const VirtualList = ({ data }) => { const containerRef = useRef(null) const [scrollTop, setScrollTop] = useState(0) const itemHeight = 40 const containerHeight = 400 const buffer = 5 const startIndex = Math.floor(scrollTop / itemHeight) const visibleCount = Math.ceil(containerHeight / itemHeight) const endIndex = startIndex + visibleCount + buffer const visibleData = data.slice(startIndex, endIndex) return ( <div ref={containerRef} style={{ height: containerHeight, overflow: 'auto' }} onScroll={(e) => setScrollTop(e.currentTarget.scrollTop)} > <div style={{ height: data.length * itemHeight }}> <div style={{ transform: `translateY(${startIndex * itemHeight}px)` }}> {visibleData.map(item => ( <div key={item.id} style={{ height: itemHeight }}> {item.name} </div> ))} </div> </div> </div> ) }

DOM 永远只有几十个


四、进阶:不定高虚拟列表(真实项目常见)

难点

  • 表格内容不确定

  • 操作列 / 多行文本 / 自动换行

解决思路

方案一(推荐):高度缓存 + 二分查找
const heightMap = new Map<index, height>()
  • 首次渲染测量高度

  • 缓存起来

  • 用累计高度数组做滚动定位

👉 react-window、react-virtual 都是这个思路


方案二:估算高度 + 滚动修正
  1. 先用estimatedHeight

  2. 渲染后真实测量

  3. 修正scrollTop


五、直接用成熟库(强烈推荐)

1️⃣ react-window(轻量,首选)

npm i react-window
import { FixedSizeList as List } from 'react-window' <List height={600} itemCount={10000} itemSize={40} width="100%" > {({ index, style }) => ( <div style={style}>{data[index].name}</div> )} </List>

👉性能极好、API 简单


2️⃣ react-virtual(TanStack)

  • 不定高

  • 可横向虚拟

  • 表格/瀑布流都行

const rowVirtualizer = useVirtualizer({ count: data.length, getScrollElement: () => parentRef.current, estimateSize: () => 40, })

3️⃣ Ant Design 表格怎么办?

官方推荐组合
  • Table + react-window

  • VirtualTable(社区实现)

Antd v5 已支持virtual

<Table columns={columns} dataSource={data} scroll={{ y: 600 }} virtual />

⚠️列宽、固定列、合并单元格要测试


六、你在性能平台里如何用(结合你实际项目)

你之前提到的场景非常典型:

  • 性能查询列表

  • 性能问题 / 覆盖度表格

  • CPU 架构对比

推荐策略

场景建议
普通列表react-window
Antd 表格Antd v5 virtual 或 react-virtual
图表下方明细虚拟列表 + memo
操作列多行高度固定,避免 auto

七、常见坑(非常重要)

❌ 1. 监听 window.scroll

👉必须用容器滚动

❌ 2. key 用 index

👉 用业务唯一 id

❌ 3. 频繁 setState

👉requestAnimationFrame/ 节流

❌ 4. 虚拟 + 动画

👉 几乎一定卡


八、性能组合拳(虚拟列表 ≠ 万能)

虚拟列表必须配合

  • React.memo

  • useCallback

  • 列 render 函数拆分

  • 避免匿名函数

  • 避免同步计算


九、总结一句话

虚拟列表的本质不是“快”,而是“DOM 数量永远可控”

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 10:45:34

UDS NRC在CANoe CAPL脚本中的触发逻辑:手把手教程

手把手教你用CAPL精准触发UDS负响应码&#xff08;NRC&#xff09;——从协议到实战的完整闭环你有没有遇到过这种情况&#xff1a;在CANoe里做诊断测试&#xff0c;明明请求发出去了&#xff0c;ECU却“装死”不回&#xff1f;或者返回一个模糊的错误&#xff0c;根本看不出问…

作者头像 李华
网站建设 2026/5/3 9:47:17

如何快速搭建多平台音乐API:开源工具的完整使用指南

如何快速搭建多平台音乐API&#xff1a;开源工具的完整使用指南 【免费下载链接】music-api 各大音乐平台的歌曲播放地址获取接口&#xff0c;包含网易云音乐&#xff0c;qq音乐&#xff0c;酷狗音乐等平台 项目地址: https://gitcode.com/gh_mirrors/mu/music-api 还在…

作者头像 李华
网站建设 2026/5/3 13:06:44

Betaflight飞控实战手册:解决飞行性能问题的完整方案

Betaflight飞控实战手册&#xff1a;解决飞行性能问题的完整方案 【免费下载链接】betaflight Open Source Flight Controller Firmware 项目地址: https://gitcode.com/gh_mirrors/be/betaflight 你是否曾经在飞行时遇到机身抖动、响应迟钝或者电池续航不理想的问题&am…

作者头像 李华
网站建设 2026/5/1 17:03:31

RFSoC-Book终极指南:从零开始掌握软件定义无线电开发

RFSoC-Book终极指南&#xff1a;从零开始掌握软件定义无线电开发 【免费下载链接】RFSoC-Book Companion Jupyter Notebooks for the RFSoC-Book. 项目地址: https://gitcode.com/gh_mirrors/rf/RFSoC-Book 还记得第一次接触RFSoC时那种既兴奋又迷茫的感觉吗&#xff1f…

作者头像 李华
网站建设 2026/5/3 14:39:34

MyBatisPlus不香了?现在流行用Fun-ASR处理会议录音

Fun-ASR&#xff1a;让会议录音“开口说话”的智能新范式 在数字化办公的浪潮中&#xff0c;一个看似不起眼却日益凸显的问题正在困扰着越来越多的企业团队&#xff1a;如何高效利用那些堆积如山的会议录音&#xff1f; 过去&#xff0c;我们依赖人工逐字听写、使用通用语音工…

作者头像 李华
网站建设 2026/5/3 1:43:10

Qwen3-14B来了:双模式切换让AI推理更智能

导语&#xff1a;Qwen3-14B作为新一代大型语言模型&#xff0c;首次实现了思考模式与非思考模式的无缝切换&#xff0c;在保持高效对话能力的同时&#xff0c;显著提升了复杂任务的推理表现&#xff0c;为AI应用带来更灵活智能的交互体验。 【免费下载链接】Qwen3-14B Qwen3-14…

作者头像 李华