js里的防抖和節流


防抖和節流是在js性能優化方面非常重要的一環,它們主要針對的是一些短時間內會被頻繁觸發的事件,比如監聽輸入框的輸入事件來驗證表單,監聽頁面的滾動事件來實現列表的加載,窗口的 resize 事件等等,這類事件都有觸發頻次高,間隔時間很短的特點,如果這個事件的回調函數涉及到很多計算以及DOM的重繪的話,就可能會導致卡頓,影響到用戶體驗,所以我們最好是使用防抖和截流這樣的函數來優化一下。

防抖debounce

防抖的原理是在事件觸發一定毫秒之后,再執行。下面我們看一下debounce的代碼,當事件被觸發之后,首先查找是否有定時器,如果存在,則清空定時器,並重新設置。只有當定時器的延遲時間到了之后,才會執行真正的回調函數,這個回調函數做為參數fn被傳入防抖函數中,這樣當我們需要進行一些dom操作的時候,就在這個回調函數里面執行。這里我們設置默認的延遲時間為200ms,你也可以在調用防抖函數的時候,根據需要來傳入延遲的時間。

function debounce(fn,delay){
 
    let delays=delay||500;
    let timer;
    return function(){
        let th=this;
        let args=arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer=setTimeout(function () {
                timer=null;
                fn.apply(th,args);
        }, delays);
    };
}

下面我們來寫一個利用防抖函數來寫一個監聽 input 的輸入值變化的小例子。首先准備好 html 頁面,監聽這個輸入框的 change 事件,並輸出觸發的時間和 input 的值在下方。

//監聽input的輸入事件 
$('#debounceInput').on('input propertychange',debounce(function(){
    $('.print').append('<p>輸出值:'+$(this).val()+','+new Date()+'<p>');
    console.log($(this).val(),new Date())
}));

然后我們在input里面輸入值,如下圖,可以看到雖然我們輸入的值變化的很快,但是輸出確是延遲的。

節流Throttle

節流 Throttle 和防抖實現的效果類似,但是原理有一些些的不同。它保證回調在函數在一個時間段內只執行一次,通過計算時間差,如果已經執行過了,清除定時器,重新開始計時,否則就執行回調函數。

function throttle(fn, wait) {

    let last, timer;
    let interval = wait || 200;

    return function() {
        let th = this,
            args = arguments;
        let now = +new Date();
        if (now - last < interval) {
            clearTimeout(timer);
            timer = setTimeout(function() {
                last = now;
                fn.apply(th, args);
            }, interval);
        } else {
            last = now;
            fn.apply(th, args);
        }
    }

}

寫好節流函數之后,我們來用一個拖拽事件測試一下,再創建一個 html,設置元素為可拖拽,監聽這個元素的拖拽事件,可以看到這個事件執行了非常多次,演示的案例里面只是如果在這個拖拽事件的回調函數里面,有一些很復雜的計算或者操作,那么難免就會產生卡頓的體驗。

那么我們現在用上節流函數,再來測試一下,可以看到函數被調用的次數減少了很多,而且調用的時間間隔也是相等的,這就是我們節流函數在起作用啦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM