JavaScript 高級系列之節流 [throttle] 與防抖 [debounce]

1、概念

這兩個東西都是爲了項目優化而出現的,官方是沒有具體定義的,他們的出現主要是爲了解決一些短期內連續執行的事件帶來性能上的不佳和內存的消耗巨大等問題;
像這類事件通常像 scroll keyup mousemove resize等等,短期內不斷的觸發,在性能上消耗是很是大的,尤爲是一些改變DOM結構的操做;javascript

節流[throttle]與防抖[debounce]很是類似,都是讓上述這類事件在規定的事件從不斷的去觸發更改爲爲規定的時間內觸發多少次;css

節流[throttle]

節流通俗來解釋就好比咱們水龍頭放水,閥門一打開,水嘩嘩的往下流,這個秉着勤儉節約的優良傳統美德,咱們要把水龍頭關小點,最好是如咱們心意按照必定規律在某個時間間隔內一滴一滴的往下滴,這,,,好吧這就是咱們節流的概念;
換成函數來講,使用setTimeout方法,給定兩個時間,後面的時間減去前面的時間,到達咱們給定的時間就去觸發一次這個事件,這麼說太籠統的,咱們看下面的函數,這裏咱們以【scroll】爲例;html

/** 樣式我就順便寫了 **/
<style> *{padding:0;margin:0;} .scroll-box{ width : 100%; height : 500px; background:blue; overflow : auto; } .scroll-item{ height:1000px; width:100%; } </style>

------------------------

/** 先給定DOM結構;**/
<div class="scroll-box">
    <div class="scroll-item"></div>
</div>

------------------------

/**主要看js,爲了簡單我用JQ去寫了**/
<script> $(document).ready(function(){ var scrollBox = $('.scroll-box'); //調用throttle函數,傳入相應的方法和規定的時間; var thro = throttle(throFun,300); //觸發事件; scrollBox.on('scroll' , function(){ //調用執行函數; thro(); }) // 封裝函數;  function throttle(method,time){ var timer = null; var startTime = new Date(); return function(){ var context = this; var endTime = new Date(); var resTime = endTime - startTime; //判斷大於等於咱們給的時間採起執行函數; if(resTime >= time){ method.call(context); //執行完函數以後重置初始時間,等於最後一次觸發的時間 startTime = endTime; } } } function throFun(){ console.log('success'); } }) </script>複製代碼

經過以上的函數,咱們就能夠作到節流的效果,在規定的每300毫秒觸發一次,固然時間能夠自定義,根據需求來;java

防抖[debounce]

寫代碼以前,咱們先清楚一下防抖的概念,不知道你們有沒有作過電腦端兩邊懸浮廣告窗口的這麼一個東西,當咱們拖動滾動條的時候,兩邊的廣告窗口會由於滾動條的拖動,而不斷的嘗試着去居於中間,而後你就會看到這兩個窗口,不停的抖啊抖;瀏覽器

通常這種就叫抖動了,咱們要作的就是防止這種抖動,稱爲防抖[debounce ];bash

那這裏防抖思想就是當咱們拖動完成以後,兩邊的窗口位置再從新去計算,這樣,就會顯得很平滑,看着很舒服了,最主要的操做DOM結構的次數就大大減小了;函數

優化了頁面性能,下降了內存消耗,否則你像IE這種比較老點版本的瀏覽器,說不定就直接給你蹦了性能

用書面一點的說法就是,在某個事件沒有結束以前,函數不會執行,當結束以後,咱們給定延時時間,然他在給定的延時時間以後再去執行這個函數,這就是防抖函數;優化

來看代碼:ui

//將上面的throttle函數替換爲debounce函數;
function debounce(method,time){
    var timer = null ;
    return function(){
        var context = this;
        //在函數執行的時候先清除timer定時器;
        clearTimeout(timer);
        timer = setTimeout(function(){
            method.call(context);
        },time);
    }
}複製代碼

思路就是在函數執行以前,咱們先清除定時器,若是函數一直執行,就會不斷的去清除定時器中的方法,知道咱們操做結束以後,函數纔會執行;

其實書寫的方式有不少,主要仍是思路的問題,你們寫的多了,天然就知道了;

用途

  1. 當咱們作keyup像後臺請求檢驗的時候,可使用防抖函數,否則咱們每按一次鍵盤就請求一次,請求太頻繁,這樣當咱們結束按鍵盤的時候再去請求,請求少不少了,性能天然不用說;
  2. resize 窗口大小調整的時候,咱們能夠採用防抖技術也可使用節流;
  3. mousemove 鼠標移動事件咱們既能夠採用防抖也可使用節流;
  4. scroll 滾動條觸發的事件,固然既能夠採用防抖也能夠採用節流;
  5. 連續高頻發的事件均可以採用這兩種方式去解決,優化頁面性能;

具體的採用哪種更較爲合適,主要仍是看你的業務需求,好了,本篇就到這裏了,感謝你們閱讀;


手打不易,總結不易,轉載請註明出處,感謝;

相關文章
相關標籤/搜索