无限滚动应使用节流而非防抖,因节流能保证定期检测是否触底,避免漏加载;防抖则可能因用户停止滚动而延迟或错过触发。

节流(throttle)是控制函数执行频率的有效手段,特别适合用在页面无限滚动(infinite scroll)场景中,防止滚动事件频繁触发导致重复请求、卡顿或资源浪费。
为什么无限滚动要用节流而不是防抖
无限滚动的核心逻辑是:当用户滚动到页面底部附近时,触发加载下一页数据。这个判断需要持续监听 scroll 事件,但 scroll 触发极频繁(每秒数十次),直接在 scroll 中调用加载函数会导致:
- 短时间内多次发起相同请求(如都去拉第 2 页)
- DOM 判断(如
scrollTop + clientHeight >= scrollHeight - 100)反复执行,影响性能 - 可能因异步未完成而并发加载,打乱数据顺序
防抖(debounce)会把多次触发“合并”成最后一次,但滚动到底部时用户可能已停止滚动,却因延迟错过加载时机;而节流能保证“至少每隔固定时间执行一次”,既控频又不丢关键触发点——更适合滚动到底部的主动检测场景。
一个轻量可靠的节流函数实现
无需依赖 Lodash,手写一个符合需求的节流函数即可:
function throttle(fn, delay) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}说明:
- 只记录上一次执行时间,不使用定时器,避免闭包内存残留和清除麻烦
- 适用于无状态的检测逻辑(如“是否该加载”),不用于直接发请求本身
- 推荐 delay 设为 100~200ms:太小起不到限制作用,太大可能延迟感知(比如滚动后半秒才加载)
结合滚动监听的实际用法
典型结构如下(以原生 JS 为例):
let loading = false; // 防止重复加载
const loadMore = () => {
if (loading) return;
loading = true;
fetch('/api/list?page=' + (currentPage + 1))
.then(res => res.json())
.then(data => {
appendToDom(data);
currentPage++;
})
.finally(() => loading = false);
};
<p>const checkShouldLoad = () => {
const { scrollTop, clientHeight } = document.documentElement;
const scrollHeight = document.body.scrollHeight;
if (scrollTop + clientHeight >= scrollHeight - 200) {
loadMore();
}
};</p><p>// 节流包装检测函数
const throttledCheck = throttle(checkShouldLoad, 150);</p><p>window.addEventListener('scroll', throttledCheck);</p>关键细节:
-
节流对象是
checkShouldLoad,不是loadMore:确保判断逻辑不频繁执行,但加载本身由业务逻辑控制(含 loading 状态) - 保留
loading标志:节流不能替代并发控制,二者配合更健壮 - 距离底部
-200px预加载:提升用户体验,避免用户看到空白再等加载
进阶建议:用 Intersection Observer 替代 scroll 监听(推荐)
现代方案更推荐用 IntersectionObserver 监听“底部占位元素”是否进入视口,它天然不依赖 scroll 事件,无性能负担,也无需节流:
const sentinel = document.getElementById('sentinel');
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && !loading) {
loadMore();
}
},
{ threshold: 0.1 }
);
observer.observe(sentinel);优势:
- 完全脱离 scroll 事件,零节流需求
- 浏览器原生优化,性能更好,兼容性已覆盖主流浏览器(包括 iOS Safari 12.2+)
- 代码更语义化、易维护
若需兼容老版本(如 IE),再回退到节流 + scroll 方案即可。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











