节流在无限滚动中应谨慎使用,因其固定间隔执行可能导致检测延迟或遗漏加载时机;推荐结合状态锁与距离判断,仅用节流限制“是否接近底部”的检查频率,确保不重复请求。

在无限滚动场景中,节流(Throttle)主要用于防止滚动事件过于频繁触发导致重复请求或性能问题,但它不是最推荐的方案——更合适的是防抖(Debounce)或基于滚动位置 + 状态锁的手动控制。不过若你确实需要在滚动中使用节流来限制“检查是否该加载”的频率,下面讲清楚怎么安全、有效地用。
为什么节流在无限滚动里要谨慎用?
节流会固定时间间隔执行一次函数(比如每 200ms 最多检查一次),但无限滚动的关键判断逻辑是:是否滚动到底部附近。如果用户缓慢滚动或停在临界区域,节流可能导致检测延迟,错过加载时机;而快速滚动又可能因节流丢掉本该触发的检查。
相比之下,防抖更适合“等用户停下再检查”,而加状态锁(如 loading = true)+ 距离判断更精准可靠。
节流函数的简单实现(不依赖 Lodash)
你可以用闭包写一个轻量节流:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function throttle(func, delay) {
let lastCall = 0;
return function (...args) {
const now = Date.now();
if (now - lastCall >= delay) {
func.apply(this, args);
lastCall = now;
}
};
}注意:这个版本是「定时器节流」的简化版(无 trailing edge),适合高频滚动中做轻量判断,不用于发起请求本身。
正确用法:节流只用于“检查是否接近底部”,请求交给状态控制
把节流用在 scroll 监听器里,仅做条件判断;真正发请求前必须加 loading 锁和距离阈值校验:
- 用节流包裹“是否快到底部”的计算逻辑(比如每 150ms 最多算一次)
- 每次计算时,先判断
document.documentElement.scrollHeight - window.scrollY <= window.innerHeight + 200(预留 200px 提前加载) - 只有同时满足「接近底部」且
!loading才调用加载函数,并立即设loading = true - 请求成功/失败后,再设
loading = false
完整示例(节流 + 状态锁 + 距离判断)
不依赖外部库,可直接运行:
let loading = false;
<p>function loadMore() {
if (loading) return;
loading = true;
// 实际请求,例如 fetch('/api/items?offset=...').then(...)
fetchMoreData().finally(() => loading = false);
}</p><p>const checkAndLoad = throttle(() => {
const { scrollHeight, scrollTop } = document.documentElement;
const windowHeight = window.innerHeight;
const threshold = 200;</p><p>if (scrollHeight - scrollTop <= windowHeight + threshold && !loading) {
loadMore();
}
}, 150);</p><p>window.addEventListener('scroll', checkAndLoad);这里节流保护的是 checkAndLoad 的执行频率,核心逻辑仍靠距离判断和 loading 锁保障不重复请求。

















