scroll
, resize
, input
, mousemove
와 같은 이벤트는 짧은 시간 간격으로 연속해서 발생합니다. 이러한 이벤트에 바인딩한 이벤트 핸들러는 과도하게 호출되어 성능에 문제를 일으킬 수 있습니다.
디바운스(Debounce)
와 스로틀(Throttle)
을 통해 짧은 시간 간격으로 연속해서 발생하는 이벤트를 그룹화해서 과도한 이벤트 핸들러의 호출을 방지할 수 있습니다.
디바운스는 짧은 시간 간격으로 이벤트가 연속해서 발생하면 이벤트 핸들러를 호출하지 않다가 일정 시간이 경과한 이후에 이벤트 핸들러가 한 번만 호출되도록 합니다. 즉, 디바운스는 짧은 시간 간격으로 발생하는 이벤트를 그룹화해서 마지막에 한 번만 이벤트 핸들러가 호출되도록 합니다.
(출처: https://kellis.tistory.com/142)
function debounce(callback, delay) {
let timeout;
return () => {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(callback, delay)
}
}
디바운스 함수에 두 번째 인수로 전달한 시간(delay)보다 짧은 간격으로 이벤트가 발생하면 이전 타이머를 취소하고 새로운 타이머를 재설정한다.
따라서 delay보다 짧은 간격으로 이벤트가 연속해서 발생하면 debounce 함수의 첫 번째 인자로 전달된 콜백 함수는 호출되지 않다가 delay동안 이벤트가 더 이상 발생하지 않으면 한 번만 호출된다.
요약
짧은 시간 간격으로 이벤트가 연속해서 발생하면 이벤트 핸들러를 호출하지 않다가 일정 시간 동안 이벤트가 더 이상 발생하지 않으면 이벤트 핸들러가 한 번만 호출.
사용 예시
- resize 이벤트 처리
- input 요소에 입력된 값으로 ajax 요청하는 입력 필드 자동완성 UI 구현
- 버튼 중복 클릭 방지 처리 등...
스로틀은 짧은 시간 간격으로 이벤트가 연속해서 발생하더라도 일정 시간 간격으로 이벤트 핸들러가 최대 한 번만 호출되도록 합니다. 즉, 스로틀은 짧은 시간 간격으로 연속해서 발생하는 이벤트를 그룹화해서 일정 시간 단위로 이벤트 핸들러가 호출되도록 호출 주기를 만듭니다.
(출처: https://kellis.tistory.com/142)
Trottle 함수의 구현은 다음과 같습니다.
function throttle(func, delay) {
let wait = false;
return () => {
if (wait) {
return;
}
wait = true
setTimeout(() => {
callback();
wait = false;
}, delay)
}
}
스로틀 함수에 두 번째 인수로 전달된 시간(delay)이 경과하기 이전에 이벤트가 발생하면 아무것도 하지 않다가 delay 시간이 경과했을 때 이벤트가 발생하면 콜백함수를 호출하고 새로운 타이머를 재설정합니다.
요약
짧은 시간 간격으로 연속해서 발생하는 이벤트를 그룹화해서 일정 시간 간격으로 이벤트 핸들러를 호출
사용 예시
- scroll 이벤트 처리
- 무한 스크롤 UI 구현