JS函数节流(throttle)与函数去抖(debounce)

背景

在浏览器 DOM 事件里面,有一些事件会随着用户的操作不间断触发。如:改变窗口大小(resize)、鼠标滚动(scroll)、鼠标移动(mousemove),如果把逻辑函数直接绑定到这些事件上,会严重影响性能,再比如把ajax请求直接绑定到keydown事件上,将在用户输入时产生频率很高的ajax请求,给服务器造成不必要的响应压力。

函数节流 (throttle)

每间隔某个时间去执行某函数,避免函数的过多执行,这个方式就叫函数节流。即设定一个时间间隔,当时间间隔大于或等于时,立即执行一次方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
function throttle(fn, delta, context) {
var safe = true;
return function() {
var args = arguments;
if(safe) {
fn.call(context, args)
safe = false
setTimeout(function() {
safe = true
}, delta)
}
}
}

函数防抖 (debounce)

固定的时间间隔内,如果事件再次被触发,则重置时间,直到大于等于时间间隔才执行方法。

1
2
3
4
5
6
7
8
9
10
11
12
function debounce(fn, delta, context) {
var timeoutID = null;
return function() {
if(timeoutID) {
clearTimeout(timeoutID);
}
var args = arguments;
timeoutID = setTimeout(function() {
fn.apply(context, args);
}, delta);
}
}

区别

throttle:一辆定时的地铁,每五分钟出发一辆,不管你有没有上到车,只要命令下来过五分钟之后就出发。

debounce:就跟电梯的原理一样,只要10s之内有人来就重置时间,再过10s,直到大于等于10s之后没人进来才出发。

小结

函数节流(throttle)和函数防抖(debounce)都是通过延时逻辑操作来提升性能的方法,在前端优化中是常见且重要的解决方式。可以从概念和实际应用中理解两者的区别,在需要的时候选择合适的方法处理。