JavaScript 的防抖和节流
防抖(Debounce) 和 节流(Throttle) 技术用于限制函数执行的次数。JS 中的一些事件如浏览器的 resize, scroll,鼠标的 mousemove, mouseover,input 输入框的 keypress 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低性能,尤其是在某些事件中进行大量计算或网络请求的情况下。这时候我们就需要通过限制函数的执行次数来优化性能。
定义
- 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
- 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
有一个经典的比喻:
想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应
假设电梯有两种运行策略 debounce 和 throttle,超时设定为15秒,不考虑容量限制
电梯第一个人进来后,不管后面有没有人进来,15秒后准时运送一次,这就是节流
电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这就是防抖
防抖(Debounce)
在事件结束后一段时间内没有再次触发事件时执行一次。
function debounce(func, delay) {
let t; // 创建计时器
return function () {
if (t) {
clearTimeout(t); // 如果计时器存在则销毁
}
t = setTimeout(func, delay); // 设置计时器
};
}
防抖的应用
- 搜索框建议项
- 消除 resize 事件处理程序的抖动
- 自动保存
- 在用户停止输入之前不发出任何 request
节流(Throttle)
无论发生什么,固定一段时间内只执行一次。
function throttle(func, limit) {
let inThrottle; // 是否在限制时间内
return function () {
if (!inThrottle) {
func();
inThrottle = ture; // 开始计时
setTimeout(() => (inThrottle = false), limit);
}
};
}
节流的应用
- 限制用户执行操作的速度
- 滚动事件处理
又水了一篇文章 😊