Debounce
와 Throttle
은 이벤트의 발생 빈도를 제한하여 최적화하는 기법이다.
본 포스팅에서는 두 기법과 차이점에 대해 소개하려한다.
디바운싱(Debounce)
이란 바운싱 현상을 방지하기 위한 기법으로, 여기서 바운싱 현상이란 다음을 의미한다.
바운싱(Bouncing)
이란 용어는 전자공학에서 기계적인 접점을 가진 스위치에서 접점이 붙거나 떨어지는 그 짧은 순간에 고속으로 여러번on/off
되는 현상을 말한다.
프로그래밍 관점에서 디바운싱이란 연속적으로 발생한 이벤트를 하나의 그룹으로 묶어서 처리하는 방식이다.
그래서 디바운싱은 연속적인 이벤트가 발생했을 때 모든 이벤트마다 AJAX 요청을 보내면 성능상 문제가 발생하기 때문에 주로 이벤트에 AJAX 요청이 묶여있을 때 사용된다.
아래 코드의 console.log
를 AJAX 요청이라 가정한다면, 사용자는 키보드를 누를 때마다 서버로 AJAX 요청을 보내게 된다.
document.querySelector('input').addEventListener('input', function(e) {
console.log('AJAX 요청!!', e.target.value);
});
위의 방법보다는 사용자가 입력을 중지했을 때 한번만 서버로 요청을 보내는 아래와 같은 방법이 더 효율적이다.
const debounce = callback => {
let timer = null;
return event => {
if(timer) clearTimeout(timer); // 타이머 초기화
timer = setTimeout(() => callback(event), 300); // 이벤트 실행
};
};
document.querySelector('input').addEventListener('input',
debounce(e => console.log('AJAX 요청!!', e.target.value))
);
해당 방식은 사용자의 마지막 입력을 감지하여 300ms
가 지나지 않았다면 이전에 등록한 타이머를 초기화한 뒤 타이머를 재등록한다.
만약 300ms
동안 아무 입력이 없다면 마지막 이벤트를 실행하여 보다 효율적으로 서버 자원을 사용할 수 있게 된다.
디바운싱에서 마지막 이벤트를 처리하는 것을 Trailing Edge
, 처음 발생한 이벤트를 처리하는 것을 Leading Edge
라고 한다.
Leading Edge
는 연속적인 이벤트가 발생되면 첫 이벤트만을 처리하여 이 후의 이벤트는 모두 무시한다.
Trailing
과 Leading Edge
를 모두 처리해주는 디바운스 함수는 다음과 같이 구현할 수 있다.
const debounce = (callback, wait, leading = false) => {
let timer;
return (event) => {
// callNow를 통해 콜백함수의 실행시점을 조절
const callNow = leading && !timer;
const later = () => {
timer = null;
if(!leading) callback(event);
};
clearTimeout(timer);
timer = setTimeout(later, wait);
if(callNow) callback(event);
};
};
Throttle
은 출력을 조절한다는 의미
쓰로틀링(Throttle)
은 발생한 여러 이벤트를 일정 시간 동안, 한번만 실행 되도록 제한한다.
만약 쓰로틀의 설정 시간을 200ms
로 설정한다면, 해당 이벤트는 200ms
동안 최대 한 번만 발생하게 된다.
즉, 마지막 함수가 호출된 이후 일정 시간이 지나기 전까지 함수는 다시 호출될 수 없다.
쓰로틀링은 주로 스크롤 이벤트에 사용되며, 스크롤을 올리거나 내릴 때 자주 발생하는 이벤트에 적용하여 특정 시간동안 한 번만 실행되게 최적화 할 수 있다.
위 예제에 쓰로틀링을 적용하면 다음과 같다.
const throttle = callback => {
let timer;
return (event) => {
if(!timer) {
timer = setTimeout(() => {
timer = null; // 타이머 초기화
callback(event); // 이벤트 실행
}, 200);
}
};
};
document.querySelector('input').addEventListener('input',
throttle((e) => console.log('AJAX 요청!!', e.target.value))
);
[10분 테코톡] 자스민의 디바운싱과 쓰로틀링
(JavaScript) 쓰로틀링과 디바운싱 - ZeroCho Blog
바운싱(Bouncing) 현상 방지 - IT 정보기술 따라잡기! - 티스토리