JAVAScript 的節流和防抖已經是老生暢談的問題了,對于前端行業技術大牛來講不過是小菜一碟,而對于絕大多數前端小白或初級工程師,絕對是必備的知識,值得學習。
接下來小郭就帶大家一起學習“防抖”與“節流”。
防抖
不知道大家第一次看到這個詞會怎樣理解。在我第一次接觸到這個概念時,直接根據字面去理解,天真的以為是JS函數有抖動。
其實是為了防止一個函數在段時間內瘋狂執行。
那它會產生在哪些場景下呢?例如:
- 搜索框 input事件;
- 鼠標移動 mousemove事件;
- 視窗大小變化 resize事件;
當然還有很多其他的一些實際場景。再來研究一下它的防抖的原理。
原理:不希望某個事件在短時間內瘋狂觸發,影響性能,所以我們設置一個定時器,讓這個事件在一定時間延遲后再執行,如果這個延遲中間中途這個事件又觸發了,那就把上次事件綁定的定時器取消,避免了上次事件執行,然后重新設置一個定時器綁定在當前事件上。
以上是我個人對防抖的理解。比如我們改變視窗大小的時候,我們更希望在視窗大小固定的時候再去執行某個方法。
現在,我們需要一個變量指向定時器,而且這個變量應該是‘全局變量’,可以用閉包實現這個‘全局變量’。
// 防抖核心方法function debounce(fn, delay) { var timer = 0 var _delay = delay || 800 return function() { if(timer) { clearTimeout(timer) } timer = setTimeout(() => { fn() }, _delay); }}
拿到代碼馬上安排,以視窗大小改變來舉例
- 未安排防抖
function resize() { console.log('視窗改變時需要執行些什么...')}window.addEventListener('resize',resize)
效果:方法多次觸發
未防抖
- 安排防抖
function debounce(fn, delay) { var timer = 0 var _delay = delay || 800 return function () { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { fn() }, _delay); }}function resize() { console.log('視窗改變時需要執行些什么...')}window.addEventListener('resize', debounce(resize, 1000))
效果:方法只在需要的時候觸發
防抖
對比結果一目了然,如果這樣的情況發生在請求接口的場景下,防抖必然會減少服務器的壓力。這何嘗不是一種關鍵的性能優化。
節流
節流,目的很明確,就是節省流量。如果一個方法在短時間內瘋狂執行,我們希望它每隔一段時間執行。如此是不是可以節省流量呢?
節流主要使用在懶加載時請求數據,在頻繁滑動的時候,不會瘋狂請求接口,減小對服務器的壓力
// 節流核心代碼function throttle(fn, delay = 800) { var timer = 0 var _delay = delay return function(){ if(!timer) { setTimeout(() => { fn() timer = 0 }, _delay); } }}
依然是以視窗大小改變舉例:
function resize(n) { return function () { console.log('視窗改變時需要執行些什么...' + n++) }}window.addEventListener('resize', throttle(resize(1)))
效果:方法被“限量”執行,不會瘋狂執行
節流
看到現在,大家應該對“防抖”與“節流”已經掌握,關鍵還是要應用到實際的項目中。為了提升大家的代碼性能,一定要看到最后。