性能优化之函数防抖动
2019-12-05 10:11:39 70
函数防抖动是一种常见的优化高频率调用函数的手段,核心是把高频率调用的函数优化为在某一时间段内只调用一次
根据具体调用的时机可以分为两种,分别是先调用防抖
以及后调用防抖
先调用防抖
先调用防抖是指先调用函数,然后等待一段时间,在等待时间结束后再进行下一次调用,如果在等待时间结束前发生了多次调用,则只会响应第一次。调用时间线如下所示
根据这个想法,可以大致得到如下代码
<input type="text">
...
let input = document.querySelector('input');
let searchWeatherByFirstDebounce = firstDebounce(searchWeather, 500);
input.onkeyup = searchWeatherByLastDebounce;
function firstDebounce(fn, time) {
let timer = null;
return function() {
!timer ? fn.apply(this, arguments) : '';
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
}, time);
}
}
function searchWeather(e) {
fetch('http://wthrcdn.etouch.cn/weather_mini?citykey=101010100')
.then(res => res.json())
.then(res => {
// do something
});
}
...
后调用防抖
后调用防抖则是先等待一段时间,在等待时间结束后调用函数,如果在等待时间结束前再次调用,则需重新计时并等待。调用时间线如下所示
在原有代码基础上进行修改,增加后调用的防抖动方法
...
let searchWeatherByLastDebounce = lastDebounce(searchWeather, 500);
input.onkeyup = searchWeatherByLastDebounce;
function lastDebounce(fn, time) {
let timer = null;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, time);
}
}
...
将防抖动的代码合并一下,得到完整的防抖动代码
...
// isImmediately: true => 先调, false => 后调
function debounce(fn, time, isImmediately = false) {
let timer = null;
return function() {
clearTimeout(timer);
if (isImmediately) {
!timer ? fn.apply(this, arguments) : '';
timer = setTimeout(() => {
timer = null;
}, time);
} else {
timer = setTimeout(() => {
fn.apply(this, arguments);
}, time);
}
}
}
...
应用场景
keyup
、keydown
等频繁触发的事件监听表单验证、输入搜索、点击搜索
其他会频繁调用的函数等
总结
函数防抖动本质上是检测前后两次连续间隔内的函数调用
,把时间间隔内的多次
函数调用合并成一次
,从而实现对频繁调用的函数的优化
先调用防抖
是立即执行时间间隔内的第一次函数调用,应用场景相对较少后调用防抖
是执行时间间隔内的最后一次函数调用,应用场景相对较多
睿江云官网链接:https://www.eflycloud.com/home?from=RJ0032