前端怎么用惰性求值优化大数据列表渲染?
我有个页面要展示上万条数据的列表,直接渲染卡得不行。听说可以用惰性求值只处理可视区域的数据,但不知道具体咋实现。试过用 Array.prototype.slice 截取一部分,但滚动时还是卡顿明显。
有没有人用 Intersection Observer 或虚拟滚动做过类似优化?能给个简单的代码示例吗?比如只在用户滚动到某块区域时才真正生成 DOM 元素。
const data = Array.from({ length: 10000 }, (_, i) => <code>Item ${i}</code>);
// 想在这里实现惰性求值,只渲染可视区域的项
function renderVisibleItems() {
// ???
}
核心就三步:
1. 用一个固定高度的容器包住列表,设置 overflow: auto
2. 计算当前滚动位置对应的可见区域索引范围
3. 只渲染这部分 DOM,其他用空 div 占位(高度要精确)
下面是个能跑的最小示例,不依赖 IntersectionObserver,纯靠 scroll 事件和 offsetHeight 计算,性能更稳:
注意:
- ITEM_HEIGHT 必须固定,否则偏移量算不准
- 滚动事件里别做重计算,这个 demo 是最轻量的
- 真项目里建议用 React/Vue 的虚拟列表库(比如 react-window),自己手写容易踩坑(比如滚动回弹、焦点错乱)
别试 IntersectionObserver 做列表渲染,它更适合“懒加载图片”这种场景,列表滚动太频繁,observer 回调延迟会更卡。