[JS] Debounce, Throttle

자두·2021년 12월 25일
1

Javascript

목록 보기
5/5
post-thumbnail

🙂 디바운스

일정 시간 전에 이벤트가 발생하게 되면, 기존의 타이머를 취소하고 시간을 재설정하여 이벤트 호출을 방지하고, 일정 시간이 경과된 후에 이벤트 핸들러가 호출되도록 한다.

  • delay보다 짧은 간격으로 이벤트가 발생하면 계속 타이머를 재설정한다.
  • delay 동안 이벤트가 발생하지 않을 때, 비로소 이벤트 핸들러가 단 한 번, 호출된다.

🙂 스로틀

이벤트 핸들러는 일정 시간이 경과한 후에 발생한 이벤트에 대해서만 최대 한 번만 호출된다.

  • 과도한 이벤트 핸들러 호출을 방지하기 위해, 일정 시간 전에 발생한 이벤트에 대해서는 이벤트 핸들러가 호출되지 않는 호출 주기를 만든다.

  • 짧은 시간 간격으로 연속해서 발생하는 이벤트를 그룹화해서 일정 시간 간격으로 이벤트 핸들러를 호출한다.

🙂 사용 이점

기본적으로 디바운스와 스로틀은 다음과 같은 이점을 위해 사용된다.

  • 타이머 함수가 적용되어 있어, 짧은 시간 동안 연속적으로 발생하는 이벤트를 제어할 때 효율적이다.
  • 이벤트 핸들러가 과도하게 호출되어 발생되는 성능 문제를 해결할 수 있다.

🙂 이벤트 예시

디바운스 이벤트 예시

  • resize 이벤트 처리
  • input 요소에 입력된 값으로 ajax 요청을 하는 입력 필드 자동완성 UI 구현
  • 버튼 중복 클릭 방지 처리

등 이벤트 핸들러 호출이 한 번만 필요할 때 유용

스로틀 이벤트 예시

  • scroll 이벤트 처리
  • 무한 스크롤 UI 구현

등 일정 시간을 기준으로 이벤트 핸들러가 호출되어야 하는 상황에 유용


🙂 라이브러리 사용

디바운스와 스로틀을 직접 구현할 수도 있지만 불안전하다. 라이브러리를 사용하여 보다 편리하고 안전하게 사용할 수 있다.

underscore library

1) CDN URL을 사용
- 하단의 CDN URL을 script 태그의 src 속성값으로 넣어주면 된다.
<script src="..."></script>

https://cdn.jsdelivr.net/npm/underscore@1.13.2/underscore-umd-min.js
https://cdn.jsdelivr.net/npm/underscore@1.13.2/underscore-esm-min.js
https://unpkg.com/underscore@1.13.2/underscore-umd-min.js
https://unpkg.com/underscore@1.13.2/underscore-esm-min.js
https://pagecdn.io/lib/underscore/1.13.2/underscore-umd-min.js
https://pagecdn.io/lib/underscore/1.13.2/underscore-esm-min.js
https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.2/underscore-umd-min.js
https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.2/underscore-esm-min.js

2) Package installation
Node.js: npm install underscore
Meteor.js: meteor add underscore
Bower: bower install underscore

3-1) Monolithic Import (recommended)
ESM import _, { map } from 'underscore';
AMD require(['underscore'], ...)
CommonJS var _ = require('underscore');
ExtendScript #include "underscore-umd.js"

3-2) Modular Import
ESM import map from 'underscore/modules/map.js'
AMD require(['underscore/amd/map.js'], ...)
CommonJS var map = require('underscore/cjs/map.js');

lodash library

1) Installation

  • In a browser (CDN URL 사용 가능):
    <script src="lodash.js"></script>
    or
    - 하단의 CDN URL을 script 태그의 src 속성값으로 넣어주면 된다.
    <script src="..."></script>
https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js
https://cdn.jsdelivr.net/npm/lodash@4.17.21/_arrayFilter.js
https://cdn.jsdelivr.net/npm/lodash@4.17.21/_arrayReduce.js
  • Using npm:
$ npm i -g npm
$ npm i --save lodash
  • In Node.js:
// Load the full build.
var _ = require('lodash');

🙂 debounce, throttle과 setTimeout, setInterval의 차이

나는 debounce와 setTimeout 모두 일정 시간이 경과했을 때, 한 번만 호출한다고 생각해서 비슷하다고 생각했다.

stackoverflow에서 비슷한 질문을 찾을 수 있었는데 결론적으로 둘은 다르다.
우선 debounce는 함수 자체를 반환하고 setTimeout은 함수를 종료시킬 수 있는 id를 반환한다.

setTimeout, setInterval

  • setTimeout과 setInterval은 같은 객체 내에서는 절대 같은 id를 사용하지 않는다. (다른 객체끼리는 다른 id 풀을 사용한다.)
    따라서 해당 id로 setTimeout을 취소할 수 있다.
    - ex) setTimeout과 setInterval을 여러 번 사용했을 때
    const intervalId = setInterval(...)
    console.log('setInterval', intervalId)
    
    const timeoutId1 = setTimeout(...)
    console.log('setTimeout1', timeoutId1)
    
    const timeoutId2 = setTimeout(...)
    console.log('setTimeout2', timeoutId2)
    
    setInterval: 1
    setTimeout1: 2
    setTimeout2: 3
    setInterval: 4
    setInterval: 5
    setInterval: 6
    ...

debounce, throttle

debounce와 throttle은 각각의 콜백 함수를 반환한다.

🙂 요약

REF

모던 자바스크립트 Deep Dive (책)
PoiemaWeb - function
Underscore
Lodash
stackoverflow

profile
블로그 이사했어요 https://ktmihs.tistory.com/

1개의 댓글

comment-user-thumbnail
2021년 12월 28일

잘봤습니다 자두님~~

답글 달기