节流是固定时间间隔内最多执行一次回调,用于降低高频事件如mousemove的cpu消耗;核心靠时间戳或定时器实现“锁”,推荐时间戳版;进阶可用requestanimationframe实现每帧一次的平滑节流。

节流(Throttle)是控制高频事件(比如 mousemove)执行频率的常用手段,核心思想是:**固定时间间隔内最多只执行一次回调**。对鼠标移动坐标监听来说,它能避免每像素移动都触发处理逻辑,显著降低 CPU 消耗和重绘压力。
节流的基本实现原理
节流的关键在于“锁”——在一次执行开始后,设定一个冷却期(如 16ms 或 50ms),期间忽略新触发;冷却结束后才允许下一次执行。
常见实现方式有两种:
-
定时器节流:首次触发立即执行,之后用
setTimeout设置延迟,在延迟未完成前的新触发被丢弃;延迟结束时再清空定时器,为下次触发做准备。 - 时间戳节流:记录上一次执行的时间戳,每次触发时对比当前时间,只有间隔超过阈值才执行并更新时间戳。
推荐的节流函数写法(时间戳版)
简洁、无副作用、适合 mousemove 场景:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
function throttle(fn, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}使用示例:
const handleMove = throttle((e) => {
console.log('X:', e.clientX, 'Y:', e.clientY);
}, 50); // 每 50ms 最多执行一次
<p>document.addEventListener('mousemove', handleMove);</p>结合防抖或 requestAnimationFrame 的进阶考虑
单纯节流适合「持续反馈」场景(如拖拽、画布绘制),但若只需「最终位置」,可考虑防抖;若追求视觉流畅(如跟随光标动画),requestAnimationFrame 更优:
- RAF 节流:把回调塞进浏览器下一帧,天然与刷新率同步(约 16.7ms),且不会阻塞渲染:
let isRafPending = false;
function rafThrottle(fn) {
return function(e) {
if (!isRafPending) {
isRafPending = true;
requestAnimationFrame(() => {
fn(e);
isRafPending = false;
});
}
};
}
<p>document.addEventListener('mousemove', rafThrottle((e) => {
// 每帧最多执行一次,平滑高效
}));</p>实际监听中要注意的细节
- 节流函数返回的是新函数,需确保事件监听器引用的是节流后的版本,避免重复绑定导致失效。
- 若监听目标是特定元素(非
document),注意事件委托或正确绑定目标节点。 - 移动端需同时监听
touchmove,节流逻辑可复用,但注意坐标取e.touches[0]。 - 调试时可通过
console.timeLog或 Performance 面板验证实际触发频率是否符合预期。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










