防抖(Debounce)和节流(Throttle)是前端开发中最常用的两种性能优化手段。它们的核心思路都是用时间换空间——限制高频事件的触发频率。
防抖的思想很简单:触发事件后,如果一段时间内没有再次触发,才执行回调。就像电梯等人——门开了之后,有人进来就重新计时,直到没人进来了才关门。应用场景:搜索框输入联想、窗口 resize 结束后执行。
节流则不同:规定一个时间段内,最多执行一次。就像地铁的闸机——刷卡后必须等门关上再刷下一次才能生效。应用场景:滚动事件监听、按钮重复点击防护。
下面是最精简的实现——两段代码加起来不超过 20 行:
// 防抖
function debounce(fn, delay = 300) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// 节流
function throttle(fn, delay = 300) {
let last = 0;
return function (...args) {
const now = Date.now();
if (now - last >= delay) {
last = now;
fn.apply(this, args);
}
};
}
防抖保证了执行时机在上次触发后的固定延迟。而节流保证了固定间隔内的稳定执行频率。闭包里的 timer 和 last 各自维持着不同的状态,互不干扰。
一个实用的进阶:如果希望防抖第一次触发就立即执行(比如提交按钮),可以加一个 immediate 参数,控制是否立即执行第一次。
这两种模式在实际项目里几乎每天都会用到——搜索框、滚动懒加载、按钮防连点,理解清楚了,写起来就是肌肉记忆的事了。