防抖(debounce)与节流(throttle)的区别
发布:elantion 日期:2020-11-28 阅读:334 评论:0
在写事件处理时,例如滚动事件,如果事件回调比较耗性能,为了不使页面卡顿,一些前辈经常会让我们写”防抖“,但有些人就说不对,应该用”节流“。刚开始看这两个概念时也不太好区分,它们究竟有什么区别呢?
节流 Throttle
日常生活中,水龙头出水太大了,就扭小一点,这种行为就叫节流。也就是说,我们限制每段时间的出水量。程序里的节流也差不多,主要是希望每一小段时间只执行一次,例如每100毫秒只执行一次。像下图:
| x | x | x |
| 100ms | 100ms | 100ms |
这里的x
就是事件函数的执行,限制了每100ms只执行一次。具体的代码类似这样:
let isThrottling = false;
setInterval(() => isThrottling = true, 100);
window.onscroll = function() {
if (isThrottling){
return;
}
isThrottling = true;
// heavy job
};
当然,这只是示例代码,实际场景需要适当做些修改,不过意思差不多就是这样。
防抖 Debounce
防抖意思就是事件函数执行完之后,等一小段时间才能再执行。同样的,我们希望事件函数执成完,等100ms后才能再次被执行,实现类似下图的情况:
| | x | | x | | x |
| 100ms |8ms| 100ms | 12ms | 100ms |4ms|
与节流不同,执行时间是不算进时间间隔的,简单来说,就是函数执行完之后必须要等上一段时间才能再次执行。
看看示例代码:
let isDebouncing = false;
window.onscroll = function() {
if (isDebouncing){
return;
}
isDebouncing = true;
// heavy job start
// ...
// heavy job done
setTimeout(() => isDebouncing = false, 100);
};
所以,如果事件函数执行非常耗时,例如超100ms,在节流模式下,函数的执行可能会横跨两个100ms,但在防抖模式下就不会有这种情况了。
复杂场景
上面都是比较简单的场景,主要是方便理解,但现实中有许多比较复杂的场景,例如我们需要事件触发时,是先执行函数再防抖,还是先防抖再执行;节流模式下希望某段时间执行两次到多次,是先执行还是先节流;等等。这里就不展开了,大家有兴趣可以阅读下面文章: