虚拟列表/虚拟滚动

📅 2026/7/5 2:48:50
虚拟列表/虚拟滚动
一、是什么页面上有很多条数据但浏览器并不一次性渲染全部 DOM只渲染用户当前能看到的那一小部分。因为dom节点渲染太多比如十万条数据十万个 DOM很容易卡顿、白屏、滚动不流畅甚至页面崩溃。虚拟列表就是一种性能优化技术。它让页面看起来像是有完整的大列表但实际上只渲染可视区域附近的数据比如十万条只渲染出了窗口的那 45 条 底下 5 条多渲染 5 条保底不会一滚动下去是空白的其他看不见的内容不渲染。虚拟滚动是实现虚拟列表的一种滚动机制。它的核心是监听滚动容器的scrollTop计算当前应该显示哪几条数据只渲染这几条用一个“占位高度”撑开滚动条让用户感觉列表真的很长二、虚拟滚动核心计算逻辑固定高度虚拟列表// 每一项列表数据的高度单位是 px const itemHeight 50; // 滚动容器的高度单位是 px const containerHeight 500; function onScroll(e) { // 获取当前滚动容器已经向上滚动的距离 // 例如 scrollTop 1000表示内容已经向上滚动了 1000px const scrollTop e.target.scrollTop; // 根据滚动距离计算当前应该从第几条数据开始渲染 // 比如 scrollTop 1000itemHeight 50 // 那么 startIndex 1000 / 50 20 // 表示应该从第 20 条数据开始显示 const startIndex Math.floor(scrollTop / itemHeight); // 计算当前容器可视区域内最多能显示多少条数据 // 比如 containerHeight 500itemHeight 50 // 那么 visibleCount 500 / 50 10 // 表示屏幕中大约能看到 10 条数据 const visibleCount Math.ceil(containerHeight / itemHeight); // 计算结束渲染的位置 // startIndex visibleCount 表示刚好渲染可视区域内的数据 // 5 表示额外多渲染 5 条作为缓冲区避免滚动时出现空白 const endIndex startIndex visibleCount 5; // 从完整列表 list 中截取当前真正需要渲染的数据 // 例如 list.slice(20, 35)表示只渲染第 20 条到第 34 条 const visibleData list.slice(startIndex, endIndex); // 计算当前这批可见数据应该整体向下偏移多少 // 因为前面的数据虽然没有被真实渲染但它们原本占据高度 // 所以需要用 offsetY 把当前数据移动到正确位置 const offsetY startIndex * itemHeight; }三、虚拟滚动核心计算逻辑动态高度虚拟列表