1. 程式人生 > 實用技巧 >JS進階篇1---函式節流(throttle)

JS進階篇1---函式節流(throttle)

javascript效能優化 釋出於 2019-06-25

JS中的函式節流

一、什麼是函式節流(throttle)

概念:限制一個函式在一定時間內只能執行一次。

舉個栗子,坐火車或地鐵,過安檢的時候,在一定時間(例如10秒)內,只允許一個乘客通過安檢入口,以配合安檢人員完成安檢工作。上例中,每10秒內,僅允許一位乘客通過,分析可知,“函式節流”的要點在於,在一定時間之內,限制一個動作只執行一次。

二、為什麼需要函式節流

  前端開發過程中,有一些事件或者函式,會被頻繁地觸發(短時間按內多次觸發),最常見的例如,onresize,scroll,mousemove,mousehover等,這些事件的觸發頻率很高,不做限制的話,有可能一秒之內執行幾十次、幾百次,如果在這些函式內部執行了其他函式,尤其是執行了操作 DOM 的函式(瀏覽器操作 DOM 是很耗費效能的),那不僅會造成計算機資源的浪費,還會降低程式執行速度,甚至造成瀏覽器卡死、崩潰。這種問題顯然是致命的。

除此之外,重複的 ajax 呼叫不僅可能會造成請求資料的混亂,還會造成網路擁塞,佔用伺服器頻寬,增加伺服器壓力,顯然這個問題也是需要解決的。

三、函式節流如何解決上述問題

根據上面對問題的分析,細細思索,問題的解決方案就呼之欲出了。

主要實現思路就是通過setTimeout定時器,通過設定延時時間,在第一次呼叫時,建立定時器,先設定一個變數true,寫入需要執行的函式。第二次執行這個函式時,會判斷變數是否true,是則返回。當第一次的定時器執行完函式最後會設定變數為false。那麼下次判斷變數時則為false,函式會依次執行。目的在於在一定的時間內,保證多次函式的請求只執行最後一次呼叫。

四、函式節流的程式碼實現

根據以上分析,我們對“函式節流”進行程式碼實現,如下:

(1)方法一:時間戳方案

// 時間戳方案
function throttle(fn,wait){
    var pre = Date.now();
    return function(){
        var context = this;
        var args = arguments;
        var now = Date.now();
        if( now - pre >= wait){
            fn.apply(context,args);
            pre = Date.now();
        }
    }
}

function handle(){
    console.log(Math.random());
}
    
window.addEventListener("mousemove",throttle(handle,1000));

(2)方法二:定時器方案

// 定時器方案
function throttle(fn,wait){
    var timer = null;
    return function(){
        var context = this;
        var args = arguments;
        if(!timer){
            timer = setTimeout(function(){
                fn.apply(context,args);
                timer = null;
            },wait)
        }
    }
}
    
function handle(){
    console.log(Math.random());
}
    
window.addEventListener("mousemove",throttle(handle,1000));
以上兩種方法本人都親自測試過,小夥伴們可以放心食用(注意,例子中函式觸發方式為“ mousemove ”,滑鼠在頁面上移動,觀察瀏覽器控制檯的變化),自己執行程式碼體驗後,自然會更深刻的理解 “函式節流” 。

五、函式節流的使用場景

到此為止,相信各位應該對函式節流有了一個比較詳細的瞭解,那函式節流一般用在什麼情況之下呢?

  1. 懶載入、滾動載入、載入更多或監聽滾動條位置;
  2. 百度搜索框,搜尋聯想功能;
  3. 防止高頻點選提交,防止表單重複提交;

目前遇到過的使用場景就是這些了,不過理解了原理,小夥伴可以把它運用在需要用到它的任何場合,提高程式碼質量。

總結

使用“函式節流”的主要目的,是為了優化程式效能,提高使用者體驗,不過最主要的為了節約計算機資源,推薦在合適的場合使用它,才能達到它應有的效果,切忌濫用哦!