throttleとdebounceを使って連続したイベント処理の負荷軽減を行う

image.png (59.9 kB)

TOC

スクロールイベントやリサイズイベントは、設定したイベントが動作の度に呼び出されてしまう為、処理が多くなりブラウザへの負荷がかかってしまいます。 負荷軽減対策の1つとして、throttledebounceを駆使して処理を軽減させる方法があります。

概要

それぞれどんな処理を行うのか、簡単に記載いたします。

【throttle】

  • 連続したイベント処理を、指定した一定間隔実行させない

【debounce】

  • 連続したイベント処理を、指定した時間内複数発生した場合でも、最後の1回だけ実行

実装

言葉だけではピンとこないと思うのでそれぞれコードで解説したいと思います

throttle

// スクロールイベント
function scrollEvent() {
  console.log('スクロール!')
}

// 間引きをする時間
const delayTime = 1000

function throttle(fn, delay) {
  // 初回実行の為、runTimeに代入する値は、現在時刻より前に設定
  let runTime = Date.now() - delay
  return () => {
    // 前回実行した時間 + 間引き時間が、現在の時間より前の場合、引数に渡した関数を実行
    if ((runTime + delay) < Date.now()) {
      runTime = Date.now()
      fn()
    }
  }
}

window.addEventListener('scroll', throttle(scrollEvent, delayTime))

debounce

// スクロールイベント
function scrollEvent() {
  console.log('スクロール!')
}

// イベントを制限する時間
const intervalTime = 100

function debounce(fn, interval) {
  let timer
  return () => {
    // setTimeoutでinterval秒処理を待ち関数を実行
    // debounce関数ががinterval秒内で複数呼び出されても、都度clearTimeoutを実行し、最後の1回だけ実行する
    clearTimeout(timer)
    timer = setTimeout(function() {
      fn()
    }, interval)
    console.log(timer)
  }
}

window.addEventListener('scroll', debounce(scrollEvent, intervalTime))

その他

今回はJavaScriptで実装しましたが、lodash.jsなどのライブラリには、すでにthrottleやdebounce関数が用意されていますし、jQueryにもプラグインが用意されています。

もし今実装しているアプリケーションでブラウザ負荷の課題がある場合は、是非試してみてはいかがでしょうか?

参考

https://aloerina01.github.io/blog/2017-08-03-1 https://iwb.jp/javascript-throttle-debounce-event-thinning-process/

CONTACT
© 2023, Kakkiii All Rights Reserved.