防抖和節流屬於性能優化
,在進行窗口的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);
}
}
}
複製代碼