前端虚拟滚动列表:优化大型数据展示的利器 ✨
在前端开发的世界里,随着应用程序的复杂性不断增加和数据量的急速膨胀,我们面临着一个艰巨的任务:如何高效展示大型数据列表?传统的滚动列表在面对庞大数据时表现疲态,加载时间拉长、性能下降,用户体验也随之下降。但别担心,前端虚拟滚动列表闪亮登场,为我们解决了这一难题。本文将深入探讨前端虚拟滚动列表的魅力所在,以及它如何成为优化大型数据展示的得力助手。
问题背景
在传统的前端开发中,当我们需要展示大量数据时,通常会采用简单的滚动列表,比如通过 <ul>
和 <li>
元素组成的列表。然而,随着数据量的急速增加,这种简单的滚动列表逐渐显得力不从心,表现出以下问题:
-
DOM 元素爆炸: 大型数据列表需要庞大的DOM元素来呈现,这导致浏览器的渲染时间明显增加,影响了页面的加载和交互性能。
-
内存消耗暴涨: 每个列表项都在内存中占用一定的空间,当数据量庞大时,内存的占用呈现不容忽视的增长,可能导致页面的崩溃或者运行变得缓慢。
-
加载时间拉长: 一次性加载庞大数据需要较长的时间,这使得用户在等待数据加载完成时可能会感到不耐烦,从而影响了整体的用户体验。
前端虚拟滚动列表的解决方案
前端虚拟滚动列表通过巧妙的策略,为我们解决了上述问题:
-
动态渲染可见区域: 只有在用户滚动到可见区域时,虚拟滚动列表才会动态地渲染这一部分的列表项,避免了一次性加载大量数据。
-
回收和重用 DOM 元素: 当列表项移出可见区域时,虚拟滚动列表会回收对应的 DOM 元素,并在需要时重用已存在的元素,减少了 DOM 元素数量和内存占用。
-
异步加载: 虚拟滚动列表可以利用异步加载机制,按需加载数据,提高页面加载速度和响应性。
这是我的一个简单的写法 使用的是
react
核心原理就是不管怎么滚动数据只展示盒子中看到的内容showDataNumber = 盒子高度 / (每一项高度 + 盒子与盒子间隔的高度)
这个算出的就是可视中看到的内容个数,我们滚动的时候需要对原数据进行切片,那么我就需要计算切片的开始位置和结束位置开始索引 = 滚动卷进去的高度 / 每项的高度
就是起始索引结束索引 = 开始索引 + (盒子高度 / 每项的高度)
就是结束的索引 然后通过slice
切出的数据就是我们要展示在可视盒子中的内容。还有一个要解决的问题就是我们需要真实的滚动条高度,这个的布局思路,展示的盒子和要滚动的盒子其实都是并行关系,滚动的时候不会让展示的盒子滚动掉,滚动的盒子我们只需要在里面加一个盒子设置高度来触滚动条 盒子高度就需要计算一下
每项的高度 * 数据总条数 + 总共的偏移量
就是滚动盒子的高度 这样就可以使我们的数据全部滚动加载出。 你会发现无论怎么滚动 dom数量一直是showDataNumber的数量。就说到这里 砸门直接看一个简单实现 :
效果:

tsx
function ScrollVirtual() {
const [dataTotal] = useState(100000)
const itemHeight = 28
const itemoffset = 8
const containerHeight = 400
const [showDataNumber] = useState(Math.round(containerHeight / (itemHeight + itemoffset)))
const offsetTotal = (showDataNumber * itemoffset)
const [list] = useState(Array.from({ length: dataTotal }, (_, index) => index + 1))
const [showData, setShowData] = useState(list.slice(0, showDataNumber))
const onScrollContainer = (e: React.UIEvent<HTMLDivElement>) => {
//虚拟列表
const scrollTop = e.currentTarget.scrollTop
const start = Math.round(scrollTop / itemHeight)
const end = Math.round(start + containerHeight / itemHeight)
const newShowData = list.slice(start, end + 1)
setShowData(newShowData)
}
return (
<>
<div style={{ height: containerHeight }} className="w-[500px] overflow-hidden relative gap-2 flex flex-col" >
<div className="w-[500px] overflow-auto" onScroll={onScrollContainer} style={{ zIndex: 100, height: containerHeight }}>
<div
className="w-full"
style={{ height: list.length * itemHeight + offsetTotal }}
></div>
</div>
<div className="absolute left-0 right-4">
{
showData.map(item => <div style={{ height: itemHeight, marginBottom: itemoffset }} className=" rounded-md bg-yellow-600 text-teal-200 text-center shadow-md shadow-yellow-600" key={item}>{item}</div>)
}
</div>
</div>
</>
)
}
结论
前端虚拟滚动列表是一项强大的优化工具,有效解决了大型数据展示时的性能问题。通过动态渲染、DOM 元素回收和异步加载等策略,虚拟滚动列表提高了用户体验,减少了页面加载时间,使得前端开发者能够更好地处理大规模数据的展示需求。在选择实现方式时,开发者可根据项目框架和需求选择合适的虚拟滚动列表工具,从而达到优化性能的目的。