防抖(Debebounce)和节流(Throttle)是前端开发中用于优化高频事件触发性能的两种常用技术,它们的核心目的是减少不必要的函数执行次数,从而提升性能。
一、防抖(Debounce)
原理
当事件被频繁触发时,防抖会延迟函数执行,直到事件停止触发一段时间(例如用户停止输入)后,才真正执行一次函数。
如果在这段延迟时间内事件再次被触发,则重新开始计时。
应用场景
- 搜索框输入联想(等待用户停止输入后再发起请求)
- 窗口大小调整(停止调整后再计算布局)
- 表单提交按钮(防止重复提交)
代码示例(简易实现)
function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer); // 每次触发时重置计时器
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
二、节流(Throttle)
原理
节流会固定时间间隔执行函数,无论事件触发有多频繁。例如,设定 500ms 的间隔,则函数在这 500ms 内最多执行一次。
应用场景
- 滚动事件(如无限滚动加载更多内容)
- 鼠标连续点击(限制点击频率)
- 游戏中的射击键(限制子弹发射速度)
代码示例(简易实现)
function throttle(func, interval) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= interval) {
func.apply(this, args);
lastTime = now;
}
};
}
三、核心区别
特性 | 防抖(Debounce) | 节流(Throttle) |
触发时机 | 事件停止触发后执行 | 按固定时间间隔执行 |
适用场景 | 避免最终状态的多次触发(如输入结束) | 限制连续高频触发(如滚动事件) |
类比 | 电梯等人:最后一个人进后关门 | 地铁发车:到点就走,不等客 |
四、进阶优化
- 防抖的立即执行版:首次触发立即执行,后续停止触发后不再执行。
- 节流的时间戳+定时器版:确保最后一次触发也会执行(如
lodash.throttle
的实现)。
总结
- 防抖:关注事件停止后的结果,适合“避免重复提交”或“最终状态确认”。
- 节流:关注过程的均匀执行,适合“限制高频操作”的场景。
根据实际需求选择合适的技术,能显著提升用户体验和性能!