防抖與節流

————— --- 圖片描述 --- ——————前端

防抖與節流

防抖(Debounce)和節流(throttle)都是用來控制某個函數在必定時間內執行多少次的技巧,二者類似而又不一樣。瀏覽器

函數節流(throttle):是讓一個函數沒法在很短的時間間隔內連續調用,當上一次函數執行後過了規定的時間間隔,才能進行下一次該函數的調用。閉包

函數去抖(debounce):讓一個函數在必定間隔內沒有被調用時,纔開始執行被調用方法。
兩個方法都是用來提高前端性能,減輕瀏覽器壓力。app

防抖(Debouncing)

像防抖仍是很容易想到的,大概意思就是延時處理,而後若是在這段延時內又觸發了事件,則從新開始延時。前端性能

// 簡單示例
    
    window.addEventListener('resize',function(e){
        var t;
        return function(){
            if(t) clearTimeout(t);
            t = setTimeout(function(){
                // do something...
            },500);
        }
    }());

節流(throttle)

爲何要函數節流函數

如下場景每每因爲事件頻繁被觸發,於是頻繁執行DOM操做、資源加載等重行爲,致使UI停頓甚至瀏覽器崩潰。性能

  • window對象的resize、scroll事件this

  • 拖拽時的mousemove事件spa

  • 射擊遊戲中的mousedown、keydown事件code

  • 文字輸入、自動完成的keyup事件

// 簡單的節流函數
function throttle(func, wait, mustRun) {
    var timeout,
    startTime = new Date();

    return function() {
        var context = this,
        args = arguments,
    curTime = new Date();

    clearTimeout(timeout);

例子以scroll事件進行解析

window.onscroll =  function(){
      lazyload();
      //throttle(lazyload,window);
 };
     function lazyload(){
     console.log("scroll執行了"+scrollnum);
}

咱們的本意只是讓鼠標滾動一次執行一次滾動函數,可是window的onscroll函數並非等scroll結束以後纔會調用,鼠標滾動或拖動滾動條,就會不停的觸發scroll事件,若是處理的東西多,低版本的IE也會陷入假死狀態。

解決辦法

debounce

抖動:若是用手指一直按住一個彈簧,它將不會彈起直到你鬆手爲止。 也就是說當調用動做n毫秒後,纔會執行該動做,若在這n毫秒內又調用此動做則將從新計算執行時間。這種比較適合window的resize事件,實際需求大多爲中止改變大小n毫秒後執行後續處理;而其餘事件大多的需求是以必定的頻率執行後續處理。針對這兩種需求就出現了和throttle兩種解決辦法。

去抖

window.onscroll =  function(){
     //lazyload();
     debounce(lazyload,window);
 };
 function debounce(method,context){
    clearTimeout(method.timeout);
    method.timeout = setTimeout(function(){
          method.call(context);
    },500);
 } 
 function lazyload(){
 console.log("scroll執行了"+scrollnum);
  }

效果以下,能夠看出只執行了一次lazyload函數:

節流以後的滾動一次的執行效果

利用定時器,讓函數執行延遲500毫秒,在500毫秒內若是有函數又被調用則刪除上一次調用,此次調用500毫秒後執行,如此往復

去抖

還有一種節流方式,是經過返回閉包的形式,能夠設置延遲時間,二者運行的結果是同樣,可是我在實際操做的時候設置延遲500時,滾動過了一會才執行了,設置爲delay爲100的時候在視覺上就沒有感受延遲。並且函數也只滾動了一次。

function debounce1(method,delay){

 var timer = null;
 return function(){
     var context = this,args = arguments;
     clearTimeout(timer);
     timer = setTimeout(function(){
         method.apply(context,args);
     },delay);
   }
 }

————— --- 圖片描述 --- ——————

上圖爲我的案例仿京東幽靈菜單 須要的親們 能夠留言 ……

相關文章
相關標籤/搜索