摘要
防抖和节流是前端优化的一部分,可以防止过多的请求。在刚开始做项目的时候还没有意识到,但是到了企业级开发或者大项目开发的时候,要考虑防抖和节流。
详细请参考js:防抖动与节流
防抖
怎么理解
防抖其实是使某一函数(请求)在用户结束操作后的规定时间后再执行。
应用场景
比如在表单输入时一般要进行非空校验,如果没有防抖的话,会在用户每输入一个字符就执行一次非空校验。
当有了防抖之后,可以使用户在停止输入后几秒再进行非空校验,这样节省函数或者接口调用的次数,以此提高性能。
代码
<script>
/* 防抖:在给定时间过去之后仅仅被调用一次
* fn为要执行的函数,delay为需要防抖的方法
* return 返回一个具有防抖功能的方法
*/
var debounce = function (fn, delay) {
// 维护一个timer
let timer = null;
return function () {
// 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
}
};
function ajax(){
console.log("执行ajax函数/其他函数,比如校验非空函数")
};
$("#input").on("input",debounce(ajax,1000));
</script>
从代码中可以看出,防抖的实质是维护一个定时器,高频事件触发时会一直使定时器清零,只有当高频事件停止后的的规定时间后,才会触发函数。
节流
怎么理解
允许一个函数在规定时间内只执行一次。
应用场景
比如在页面无限加载的场景下,每隔一段时间就发送一次请求,而不是在用户停下滚动页面操作时才去请求数据。
代码
两种方法分别是时间戳和定时器
- 时间戳: 当高频事件触发时,第一次应该会立即执行(给事件绑定函数与真正触发事件的间隔如果大于delay的话),而后再怎么频繁触发事件,也都是会每delay秒才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了
- 定时器: 当第一次触发事件时,肯定不会立即执行函数,而是在delay秒后才执行。 之后连续不断触发事件,也会每delay秒执行一次。当最后一次停止触发后,由于定时器的delay延迟,可能还会执行一次函数。
综合使用时间戳与定时器,完成一个事件触发时立即执行,触发完毕还能执行一次的节流函数
var throttle = function(func,delay){
var timer = null;
var startTime = Date.now();
return function(){
var curTime = Date.now();
var remaining = delay-(curTime-startTime);
var context = this;
var args = arguments;
clearTimeout(timer);
if(remaining<=0){
func.apply(context,args);
startTime = Date.now();
}else{
timer = setTimeout(func,remaining);
}
}
}
需要在每个delay时间中一定会执行一次函数,因此在节流函数内部使用开始时间、当前时间与delay来计算remaining,当remaining<=0时表示该执行函数了,如果还没到时间的话就设定在remaining时间后再触发。当然在remaining这段时间中如果又一次发生事件,那么会取消当前的计时器,并重新计算一个remaining来判断当前状态。