iT邦幫忙

1

JS [筆記] debounce、throttle

  • 分享至 

  • xImage
  •  

完全參考,此處為整理筆記
[有趣面試題] 網頁效能問題改善之 Debounce & Throttle
Debounce & Throttle — 那些前端開發應該要知道的小事(一)

適用情境

只要是使用者會在短時間內頻繁觸發多次事件處理器,例如:
autocomplete、滑鼠移動、改變視窗大小都可以適用此篇。因為你的瀏覽器會不斷重新計算造成頁面很緩慢

如Vue的computed因內部變數變動,致重複觸發,此時可使用debounce設定觸發時間,節省效能

<input type="text" id="debounce-input" placeholder="type something" />
<input type="text" id="throttle-input" placeholder="type something" />

debounce

所謂 Debounce,是讓使用者在觸發相同事件(如卷軸)的情境下,停止觸發綁定事件的效果,直到使用者停止觸發相同事件。

因為使用者輸入一次你就要 filter 一次,假如使用者頻繁輸入就可能會影響到效能
設一個 timeout,例如輸入以後過兩秒才去抓一次使用者輸入值
好處就是可以防止 js 頻繁去篩選資料,等待兩秒後再一次篩選就好

    // func: 要執行的 function
    // delay: 延遲幾秒才執行
    function debounce(func, delay) {
      // timeout 初始值
      let timeout = null;
      return function () {
        let context = this; // 指向 myDebounce 這個 input
        let args = arguments; // KeyboardEvent
        clearTimeout(timeout);

        timeout = setTimeout(function () {
          func.apply(context, args);
        }, delay);
      };
    }
    // 1 2秒後執行
    // 2 前一個清掉,2秒後執行 1 2
    // 3 前一個清掉,2秒後執行 1 2 3
    
    let myDebounce = document.getElementById("debounce-input");
    // myDebounce.addEventListener('keyup', function(e){
    //         console.log(e.target.value)
    // })
    
    myDebounce.addEventListener(
      "keyup",
      debounce(function (e) {
        console.log(e.target.value);
      }, 2000)
    );

throttle

為使用者觸發相同事件時提供間隔,控制特定時間內事件觸發的次數。
它防止一下輸入太頻繁的值,所以會限制一個時間,在這時間內觸發的值會被存到下一次再存

    function throttle(func, delay) {
      let inThrottle;
      let timeout = null;
      return function () {
        let context = this;
        let args = arguments;
        if (!inThrottle) {
          // 輸入之後兩秒內都不回進入這邊
          func.apply(context, args);
          inThrottle = true;
          clearTimeout(timeout);
          timeout = setTimeout(function () {
            inThrottle = false;
          }, delay);
        }
      };
    }
    
    document.getElementById("throttle-input").addEventListener(
      "keyup",
      throttle(function (e) {
        console.log(e.target.value);
      }, 2000)
    );

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言