throttleとdebounceを使って連続したイベント処理の負荷軽減を行う
TOC
スクロールイベントやリサイズイベントは、設定したイベントが動作の度に呼び出されてしまう為、処理が多くなりブラウザへの負荷がかかってしまいます。 負荷軽減対策の1つとして、throttleとdebounceを駆使して処理を軽減させる方法があります。
概要
それぞれどんな処理を行うのか、簡単に記載いたします。
【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/
Search Posts