在进行窗口的resize / scroll、输入框内容校验等操作的时候,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常差。那么为了前端性能的优化,也为了用户更好的体验,就可以采用防抖(debounce)和节流(throttle)的方式来达到这种效果,减少调用的频率。
防抖是关注于最后一次的事件触发,而节流则是在规定的时间里只执行一次。
1、防抖 (debounce)
单位时间内,频繁触发一个事件,以最后一次触发为准。
官方解释: 当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次;如果设定的时间到来之前,又触发了事件,就重新开始延时。
// 防抖函数的简单实现
var timer = null;
document.getElementsByTagName('input')[0].oninput = function debounce () {
if(timer){
clearTimeout(timer);
timer = null
}
timer = setTimeout(() => {
/* ...... */
}, 2000)
}
2、节流(throttle)
单位时间内,频繁触发一个事件,只会触发一次。
官方解释: 当持续触发事件时,保证一定时间段内只调用一次事件处理函数。
// 节流函数的简单实现
var valid = true;
document.getElementsByTagName('input')[0].oninput = function throttle () {
if(valid){
setTimeout(() => {
/* ...... */
valid = true
}, 2000);
valid = false
}
}
以上是防抖和节流的解释与简单实现,希望对大家有所帮助,
下面是通过获取新旧时间差值来和间隔时间进行比较,从而实现节流的代码示例:
const ipt = document.getElementById('ipt');
ipt.oninput = throttle(function () {
/* ...... */
}, 3000);
function throttle(fn, await) {
var old = 0; //之前时间戳
return function () {
var now = new Date(); //当前时间
if (now - old > await) {
fn();
old = now;
}
};
}
白话文解释,仅代表我个人的理解:
① 防抖,就好比在坐电梯,假设电梯停留的时间是10秒,但是当最后1秒有人进入的时候,电梯的门还会打开,方便人员进入。(在设定的时间内,频繁触发函数,计时器会重新进行计时,只要计时器没有执行完,函数内部执行语句也就不会执行)
② 节流,就好比在坐地铁,假设一个线路的地铁是15分一趟,他会按照时间严格的遵循,上不了车只能等下一班次。(在一定时间内,频繁触发函数,因为节流的表现,函数内的执行语句只会在设定的时间内触发一次)