一、throttle节流 vs debounce去抖
在开发过程中会遇到频率很高的事件或者连续的事件,如果不进行性能的优化,就可能会出现页面卡顿的现象,比如:
- 鼠标事件:mousemove(拖曳)/mouseover(划过)/mouseWheel(滚屏)
- 键盘事件:keypress(基于ajax的用户名唯一性校验)/keyup(文本输入检验、自动完成)/keydown(游戏中的射击)
- window的resize/scroll事件(DOM元素动态定位)
什么是debounce去抖
debounce的作用:当调用动作触发一段时间后,才会执行该动作,若在这段时间间隔内又调用此动作则将重新计算时间间隔
应用场景:
- 提交ajax时,不希望1s中内大量的请求被重复发送
- 对用户输入的验证,不在输入过程中就处理,停止输入后进行验证足以
实现思路:
- debounce函数会通过闭包维护一个timer
- 当同一action在delay的时间间隔内再次触发,则清理timer,然后重新设置timer
实现代码:
var debounce = function(action, delay) {
var timer = null;
return function() {
var self = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
action.apply(self, args)
}, delay);
}
}
function resizeHandler() {
console.log("resize");
}
window.onresize = debounce(resizeHandler, 300);
什么是throttle节流
throttle跟debounce的最大不同就是,throttle会有一个阀值,当到达阀值的时候action必定会执行一次。
应用场景:
- 对用户输入的验证,不想停止输入再进行验证,而是每n秒进行验证
- 对于鼠标移动和窗口滚动,鼠标的移动和窗口的滚动会带来大量的事件,但是在一段时间内又必须看到页面的效果
实现代码:
var throttle = function(action, delay){
var statTime = 0;
return function() {
var currTime = +new Date();
if (currTime - statTime > delay) {
action.apply(this, arguments);
statTime = currTime ;
}
}
}
function resizeHandler() {
console.log("resize");
}
window.onresize = throttle(resizeHandler, 300);
总结
- debounce:把触发非常频繁的事件合并成一次执行
- throttle:设置一个阀值,在阀值内,把触发的事件合并成一次执行;当到达阀值,必定执行一次事件