手把手带你实现一个Virtual Scroll虚拟滚动列表

Sarah Wong | 2026-08-27T13:30:00 | JavaScript, Frontend

10万条数据渲染不卡顿,用IntersectionObserver实现虚拟滚动的核心原理和实现

# 手把手带你实现一个Virtual Scroll虚拟滚动列表 产品说要做一个10万条数据的列表页,不让分页,说"用户体验不好"。行吧,虚拟滚动搞起。 ## 核心原理 只渲染可视区域的DOM节点,滚动时动态替换内容。10万条数据实际只有20-30个DOM节点。 ```javascript function VirtualScroll(container, items, itemHeight) { var visibleCount = Math.ceil(container.clientHeight / itemHeight); var bufferSize = 5; // 上下缓冲区 container.addEventListener('scroll', function() { var scrollTop = container.scrollTop; // 计算可见范围 var startIndex = Math.floor(scrollTop / itemHeight); var start = Math.max(0, startIndex - bufferSize); var end = Math.min(items.length, startIndex + visibleCount + bufferSize); // 只渲染可见区域的项 renderItems(items.slice(start, end), start * itemHeight); }); // 用一个撑高的空div模拟完整高度 var spacer = document.createElement('div'); spacer.style.height = (items.length * itemHeight) + 'px'; container.appendChild(spacer); } function renderItems(visibleItems, offsetY) { // 清除旧节点,渲染新节点 listEl.style.transform = 'translateY(' + offsetY + 'px)'; listEl.innerHTML = visibleItems.map(function(item) { return '' + item.name + ''; }).join(''); } ``` ## 关键优化 - **Buffer Zone**:上下各多渲染5条,避免快速滚动时出现空白 - **transform代替top**:不触发重排,用GPU加速 - **IntersectionObserver**:可以用来做懒加载图片 亲测10万条数据滚动60fps无压力,产品终于满意了。

← Back to Blog