节流技术是控制触底判断执行频率而非减慢滚动,避免重复请求、强制重排和内存泄漏;推荐定时器实现,并需配合document.documentElement、阈值设置、loading锁及监听器卸载,现代环境优先用Intersection Observer。

节流技术不是让滚动变慢,而是控制“判断是否该加载”这个动作的执行频率,避免高频触发导致重复请求、卡顿或 DOM 渲染抖动。
为什么触底加载必须加节流
滚动事件在用户滑动时每秒可能触发几十次,尤其在移动端惯性滚动中。若每次触发都执行触底判断和数据请求:
- 同一位置反复调用 loadMore(),后端收到多个相同分页请求
- 频繁读取 document.documentElement.scrollHeight、window.scrollY 等属性,引发强制同步布局(reflow)
- 短时间内多次插入 DOM 节点,造成重排重绘压力,页面出现明显卡顿
- 组件卸载后监听器未清理,this 指向丢失或引发内存泄漏
节流实现方式(推荐定时器版)
使用闭包 + setTimeout 控制最小执行间隔,确保 n 秒内最多执行一次判断逻辑:
示例代码(可直接复用):function throttle(fn, delay = 200) {
let timer = null;
return function (...args) {
if (timer) return;
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
};
}
<p>const handleScroll = throttle(() => {
const { scrollY } = window;
const { clientHeight } = document.documentElement;
const { scrollHeight } = document.documentElement;
const threshold = 200;</p><p>if (scrollY + clientHeight >= scrollHeight - threshold) {
loadMore(); // 触发加载逻辑
}
});</p><p>window.addEventListener('scroll', handleScroll);立即学习“Java免费学习笔记(深入)”;
关键细节与避坑点
仅加节流还不够,需配合以下实践才能真正稳定:
- 用 document.documentElement 而非 document.body:Safari 等浏览器中 body.scrollTop 始终为 0,会导致触底永远不触发
- 设置合理阈值(如 150–300px):提前加载,避免用户看到空白再等待,提升感知流畅度
- 加载状态锁(loading = true/false):即使节流生效,网络延迟仍可能导致快速滚动时多次进入临界区,需配合 loading 标志防重复请求
- 监听器卸载要同步:组件销毁或路由跳转前,务必调用 window.removeEventListener('scroll', handleScroll)
更优替代方案:Intersection Observer
如果目标环境支持(现代浏览器及主流小程序),优先用 Intersection Observer 替代 scroll + 节流:
- 无需手动计算 scrollY / scrollHeight,性能零开销
- 监听底部占位元素(sentinel)是否进入视口,触发精准、无误判
- 天然支持懒加载、图片解码、动画入场等多场景,扩展性强


















