窗口的resize
、scroll
,輸入框內容校驗等操做時,若是這些操做處理函數較爲複雜或頁面頻繁重渲染等操做時,若是事件觸發的頻率無限制,會加劇瀏覽器的負擔,致使用戶體驗很是糟糕。此時咱們能夠採用debounce(防抖)和throttle(節流)的方式來減小觸發的頻率,同時又不影響實際效果。javascript
debounce(防抖),簡單來講就是防止抖動。html
從上圖中咱們能夠看到,當持續觸發事件時,debounce會合並事件且不會去觸發事件,當必定時間內沒有觸發再這個事件時,才真正去觸發事件~ 一塊兒來實現個簡單的debounce:java
function debounce(fn, delay) { var ctx; var args; var timer = null; var later = function () { fn.apply(ctx, args); // 當事件真正執行後,清空定時器 timer = null; }; return function () { ctx = this; args = arguments; // 當持續觸發事件時,若發現事件觸發的定時器已設置時,則清除以前的定時器 if (timer) { clearTimeout(timer); timer = null; } // 從新設置事件觸發的定時器 timer = setTimeout(later, delay); }; }
效果圖:git
throttle(節流),當持續觸發事件時,保證隔間時間觸發一次事件。github
上圖中綠色塊表示觸發一次事件,持續觸發事件時,throttle會合並必定時間內的事件,並在該時間結束時真正去觸發一次事件~ 一塊兒來看看throttle的簡單實現:瀏覽器
function throttle(fn, delay) { var ctx; var args; // 記錄上次觸發事件 var previous = Date.now(); var later = function () { fn.apply(ctx, args); }; return function () { ctx = this; args = arguments; var now = Date.now(); // 本次事件觸發與上一次的時間比較 var diff = now - previous - delay; // 若是隔間時間超過設定時間,即再次設置事件觸發的定時器 if (diff >= 0) { // 更新最近事件觸發的時間 previous = now; setTimeout(later, delay); } }; }
效果圖:閉包
根據實際業務場景,合理的利用debounce(防抖)和throttle(節流)能夠優化性能和提升用戶體驗。二者間的核心區別就在於持續觸發事件時,前者合併事件並在最後時間去觸發事件,然後者則是隔間時間觸發一次~app
setTimeout 定時器less
w3school函數
ruanyifeng