节流是固定时间间隔内最多执行一次回调的高频事件优化手段,核心为匀速执行、维护锁状态与定时器,并支持leading/trailing选项;rafThrottle则利用requestAnimationFrame实现帧率同步的更平滑节流。

节流(Throttle)是控制高频事件(比如 scroll、resize)执行频率的有效手段,核心思路是:**固定时间间隔内最多只执行一次回调**,避免函数被频繁调用拖慢页面响应。
节流的基本原理与关键点
节流不是“等事件停了再执行”,而是“匀速执行”——哪怕用户持续滚动,也只按设定间隔(如 100ms)触发一次处理逻辑。关键在于维护一个“锁”状态和定时器,防止重复进入执行流程。
- 每次触发事件时,先检查是否处于“冷却中”(已有定时器未执行完)
- 如果未冷却,立即执行回调,并启动新的定时器,在其到期前锁定后续调用
- 定时器到期后解锁,允许下一次执行
手写一个可靠的节流函数
下面是一个带 leading(首次立即执行)和 trailing(末次补发)选项的通用实现:
function throttle(func, delay, options = {}) {
const { leading = true, trailing = false } = options;
let timer = null;
let lastExecTime = 0;
<p>return function(...args) {
const now = Date.now();
const elapsed = now - lastExecTime;</p><pre class="brush:php;toolbar:false;">if (leading && elapsed >= delay) {
func.apply(this, args);
lastExecTime = now;
return;
}
if (trailing) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
lastExecTime = Date.now();
}, delay);
}}; }
使用示例:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
window.addEventListener('scroll', throttle(() => {
console.log('滚动处理');
}, 100, { leading: true, trailing: false }));注意:trailing: true 适合需要捕捉“滚动结束”的场景(如懒加载最后一屏),但会增加一次延迟调用;多数性能优化场景推荐 leading: true, trailing: false。
用 requestAnimationFrame 实现更平滑的节流
对于视觉相关操作(如视差滚动、滚动位置计算),requestAnimationFrame 是比 setTimeout 更优的选择——它天然与屏幕刷新率同步(通常 60fps),且在页面不可见时自动暂停,更省资源。
function rafThrottle(func) {
let isQueued = false;
return function(...args) {
if (!isQueued) {
isQueued = true;
requestAnimationFrame(() => {
func.apply(this, args);
isQueued = false;
});
}
};
}
<p>window.addEventListener('scroll', rafThrottle(() => {
const scrollTop = window.pageYOffset;
// 更新元素位置、透明度等
}));这种方式每帧最多执行一次,不设固定毫秒值,更适合动画类响应。
实际应用中的注意事项
节流只是优化一环,还需配合其他策略才能真正提升滚动性能:
-
避免在 scroll 回调里强制同步重排(reflow):例如读取
offsetTop后立刻设置style.left。可改用getBoundingClientRect()或将读写分离 -
用 passive: true 提升滚动流畅度:告诉浏览器该事件监听器不会调用
preventDefault(),允许浏览器异步处理滚动 - 考虑 IntersectionObserver 替代 scroll 监听:对“元素进入视口”这类需求,它更高效、更语义化,且自动节流
不复杂但容易忽略。


















