防抖和节流属于性能优化
,在进行窗口的resize
、滚动条scroll
,输入框内容校验等操做时,若是事件处理函数调用的频率无限制,会加剧浏览器的负担,致使用户体验很是糟糕。浏览器
此时咱们能够采用debounce(防抖)和throttle(节流)的方式来减小调用频率,同时又不影响实际效果。性能优化
无论事件触发频率多高,必定在事件触发n
秒后才执行,若是你在一个事件触发的 n
秒内又触发了这个事件,就以新的事件的时间为准,n
秒后才执行。对于短期内连续触发的事件,防抖的含义就是让某个时间期限(如上面的1000毫秒)内,事件处理函数只执行一次。markdown
setTimeout
这个函数,因为还须要一个变量来保存计时,考虑维护全局纯净,能够借助闭包来实现。setTimeout
则用的箭头函数,这样作的意义是让this
的指向准确,this
的真实指向并不是debounce
的调用者,而是返回闭包的调用者。function debounce(event, time) {
let timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(()=> {
event.apply(this, args);
}, time)
}
}
// 若是须要当即执行, 加一个flag 标志, 定时器变量`timer`为空时,说明是第一次执行,咱们当即执行它。
function debounce(fn, time, flag) {
let timer = null;
return function(...args) {
clearTimeout(timer);
if(flag && !timer) {
fn.apply(this, args)
}
timer = setTimeout(()=> {
fn.apply(this, args);
}, time)
}
}
复制代码
一、窗口的resize
闭包
window.addEventListener('resize', debounce(handleResize, 200))
复制代码
二、滚动条scroll
app
function showTop() {
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log(scrolltop);
}
window.addEventListener('scroll', debounce(showTop, 1000))
复制代码
三、输入框内容校验
, 搜索框
函数
debounce(valicator/fetchSelectData, 1000)
复制代码
当持续触发事件时,保证必定时间段内只调用一次事件处理函数.
性能
节流比如水龙头放水,按照必定规律在某个时间间隔内一滴一滴的往下滴, 不开阀放水浪费;fetch
函数节流主要有两种实现方法: 时间戳和定时器
;优化
首刻发生,尾刻不发生,中间正常this
function throttle(event, time) {
let pre = 0;
return function(...args) {
if(Date.now() - pre > time) {
pre = Date.now();
event.apply(this, args);
}
}
}
复制代码
首刻不发生,尾刻发生,中间正常;
function throttle(event, time) {
let timer = null;
return function(...args) {
if(!timer) {
timer = setTimeout(()=>{
clearTimeout(timer)
timer=null;
event.apply(this, args);
}, time);
}
}
}
复制代码
function throttle(event, time) {
let pre = 0, timer = null;
return function(...args) {
if(Date.now() - pre > time) {
pre= Date.now();
timer = null
clearTimeout(timer);
event.apply(this, args)
} else if(!timer) {
timer = setTimeout(()=>{
event.apply(this, args);
}, time);
}
}
}
复制代码