在开发过程中会遇到频率很高的事件或者连续的事件,如果不进行性能优化,就可能会出现页面卡顿的现象,比如:
- 鼠标事件:
mousemove
(拖拽)、mouseover
(划过) 、mouseenter
(滚屏)
- 键盘事件:
keypress
(基于ajax
的用户名唯一性校验) 、keyup
(文本输入检验、自动完成) 、keydown
(游戏中的射击)
window
的resize
/scroll
事件
DOM
元素动态定位
为了解决这类问题,常用的方法就是throttle
(节流)和debounce
(消抖),二者都是通过控制某个函数在一定时间周期内的执行次数,看似相同实则不同。
throttle
(节流)
预先设定一个执行周期,当调用动作的时刻大于等于执行周期时执行该动作,然后进入下一个新的时间周期。
比如 你是一个门店的自主经营者,当晚上要关门下班的时候发现有人来买东西,为了照顾生意,你会耐心等该客户买完东西后再会关门,但是如果你是一个没耐心的人,且最多只会等三五分钟;在这三五分钟之内,你会等待他人进来,但是过了5分钟之后,你就会关门回家。
上代码:
function throttle(action, delay){
var timer = null;
var last = null;
return function(){
var now = +new Date();
var _action = function(){
last = now;
fn.apply(this,arguments);
}
if(last && now < last+delay){
clearTimeout(timer);
timer = setTimeout(_action,delay);
}else{
//开始结束各触发一次;
_action();
}
}
}
debounce
(消抖)
当调用动作触发一段时间后,才会执行该动作,若在这段时间间隔内又调用此动作则将重新计算时间间隔。
同样上面的例子:debounce晚上下班时间到了,你是个体经营户,在关门之前发现有客户上门,你考虑到生意问题,你会等待客户买完东西,结果又有客户上门,你依旧会等待,这样一直进行下去,你可能需要多等待几分钟,最终没人来店里买东西的,才会关上门回家。
即:把触发非常频繁的事件合并一次执行。上代码:
function debounce(action,delay){
var timer = null;
return function(){
clearTimeout(timer);
timer = setTimeout(
action.delay,
delay,
this,
arguments
)
}
}