节流函数在短视频无限滚动加载中核心作用是限制滚动事件触发频率,避免频繁请求和DOM操作;必须用节流而非防抖,因需及时响应接近底部时机,而非等待停止滑动;推荐时间戳实现,设delay为100~16ms,绑定scroll时启用passive: true,并结合加载阈值、loading锁及Intersection Observer优化。

节流函数在短视频无限滚动加载中,核心作用是限制滚动事件的触发频率,避免频繁执行数据请求或 DOM 操作,从而减少浏览器重排重绘、网络请求数量和内存占用。
为什么滚动加载必须用节流而不是防抖
无限滚动需要“用户滑到接近底部时就提前加载下一页”,这个动作需及时响应,不能等用户停下滑动才触发(那是防抖的逻辑)。节流能保证每 N 毫秒最多执行一次加载判断,既不漏掉关键时机,又不会每像素滚动都检查 scrollTop 和容器高度——后者在高刷新率屏幕或快速滑动时可能每秒触发上百次。
节流函数的关键实现细节
一个适合滚动场景的节流函数要满足三点:立即执行首次调用、固定间隔内忽略后续调用、停止触发后不补发。推荐使用时间戳方式实现,比定时器更精准且无内存泄漏风险:
function throttle(func, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
lastTime = now;
}
};
}- 不要用 setTimeout + flag 的“开关式”节流,容易因异步导致多次执行或丢失调用
- delay 建议设为 100~16ms:100ms 用户无感知卡顿,16ms(≈60fps)可兼顾响应性与性能
- 绑定 scroll 事件时,务必使用 passive: true 提升滚动流畅度(但此时不能调用 preventDefault)
结合滚动加载的完整判断逻辑
节流只是控制频率,真正节约开销还依赖合理的加载触发条件。不能只写 if (scrollTop + height >= scrollHeight),那会在临界点反复触发:
立即学习“Java免费学习笔记(深入)”;
- 预留“加载阈值”,比如距离底部 200px 就开始请求:
scrollTop + clientHeight >= scrollHeight - 200 - 加 loading 状态锁,请求中 ignore 后续节流调用:
if (loading || hasMore === false) return - 监听的是目标容器(如 .video-list),不是 window——避免页面有多个滚动区时互相干扰
更进一步:Intersection Observer 替代 scroll 监听
现代方案推荐用 IntersectionObserver 监听“底部占位元素”是否进入视口,它由浏览器原生优化,不触发重排,且自动处理节流:
- 创建一个空 div 放在列表末尾,class="infinite-loader"
- Observer 配置
{ root: null, threshold: 0.1 },10% 进入即触发 - 回调中调用加载函数,然后重新 observe(或用 unobserve + observe 切换)
- 兼容性够用(Chrome 51+/Safari 12.1+/Edge 79+),老版本再 fallback 到节流 scroll


















