滚动事件节流的核心是限制函数执行频率,通过定时器确保只在最后一次滚动后延迟执行,常用setTimeout配合clearTimeout实现,延迟时间通常设为100–200ms;也可封装为通用throttle函数或采用requestAnimationFrame提升视觉相关逻辑的渲染性能。

滚动事件节流的核心是限制函数执行频率,避免高频触发导致性能问题。关键在于用定时器控制“只在最后一次触发后延迟执行”,而不是每次滚动都调用。
用定时器实现基础节流(推荐)
这是最常用、最易理解的方式:每次触发滚动时,先清除上一个定时器,再设置新的延迟执行。
- 用 setTimeout 设置延迟执行逻辑
- 用 clearTimeout 确保旧任务被取消
- 延迟时间通常设为 100–200ms,兼顾响应性与性能
示例代码:
let scrollTimer = null;
const handleScroll = () => {
// 清除上一次未执行的定时器
if (scrollTimer) clearTimeout(scrollTimer);
// 设置新定时器,在停止滚动后 150ms 执行
scrollTimer = setTimeout(() => {
console.log('滚动结束,执行业务逻辑');
// 比如判断是否触底、更新吸顶状态等
}, 150);
};
window.addEventListener('scroll', handleScroll);
封装成可复用的节流函数
把节流逻辑抽离出来,便于多个场景复用,也更符合工程实践。
立即学习“Java免费学习笔记(深入)”;
- 接收原函数和延迟时间作为参数
- 内部维护闭包变量保存定时器 ID
- 返回一个新函数,调用时自动处理清除与重设
示例:
function throttle(fn, delay = 150) {
let timer = null;
return function (...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// 使用
const throttledScroll = throttle(() => {
console.log('节流后的滚动处理');
}, 150);
window.addEventListener('scroll', throttledScroll);
注意:节流 ≠ 防抖,别混用场景
滚动节流适合需要“滚动结束后执行一次”的情况(如懒加载、吸顶计算)。如果要实时响应滚动位置(如视差动画),应考虑 requestAnimationFrame 方案,它由浏览器调度,更平滑且性能更好。
- 防抖:连续触发只执行最后一次 → 适合搜索框输入、窗口 resize 后重排版
- 节流:固定间隔最多执行一次 → 适合 scroll、mouseMove 等高频事件
- raf 节流:每帧最多执行一次 → 更精准控制渲染时机,推荐用于视觉相关逻辑
补充:raf 版本(进阶推荐)
对于依赖滚动位置做视觉更新的场景,用 requestAnimationFrame 替代 setTimeout 更合理,因为它与屏幕刷新同步,不会丢帧或卡顿。
let isRafPending = false;
const handleScrollWithRaf = () => {
if (!isRafPending) {
isRafPending = true;
requestAnimationFrame(() => {
console.log('在下一帧执行滚动逻辑');
// 更新 DOM、计算位置等
isRafPending = false;
});
}
};
window.addEventListener('scroll', handleScrollWithRaf);


















