Input 이벤트, 스크롤 이벤트, 마우스 이벤트 등 빈번하게 발생할 때, API 호출과 같이 비용이 많이 드는 처리가 발생하는 경우가 있다.
검색 기능을 개발하거나, 스크롤에 따라 데이터가 불러지거나 하는 경우에 이벤트가 발생할 때마다 많은 트래픽이 발생하면서 비효율은 물론 성능에 까지 악영향을 끼칠 수 있다.
이런 경우를 핸들링 할 수 있는 몇가지 방법이 있다. 캐시를 만든다거나, debounce와 throttle을 적용하는 방법 등이다.
: 두 방법 모두 과도한 이벤트 발생을 막고, 제약을 통해 성능향상과 더불어 사용자 경험 향상에 도움을 주는 방법이다.
const debounce = (callback, limit = 250) => {
let timeout
return function (...args) {
clearTimeout(timeout)
timeout = setTimeout(() => {
callback.apply(this, args)
}, limit)
}
}
const debounceEvent = debounce((event) => {
const data = event.target.value.trim();
state.searchText = data;
onChangeHandler(state.searchText);
});
searchInput.addEventListener("input", debounceEvent);
: debounce에 대한 구현은 클로져함수와 timeout을 활용하여 만들 수 있다.
위 코드는 input에 텍스트 입력을 감지한 후 250ms 동안 입력이 없으면 정의된 함수를 실행한다.
-> 사용자의 입력이 완료될 때까지 불필요한 API 호출을 막을 수 있다.
const throttle = (callback, wait = 500) => {
let waiting = true;
return function(...args) {
if (waiting) {
callback.apply(this, args);
waiting = false;
setTimeout(() => {
waiting = true;
}, wait);
}
};
};
: throttle에 대한 구현도 debounce와 마찬가지로 클로져함수와 timeout을 활용하여 만들 수 있다.
만약 스크롤 이벤트 처럼 지속적으로 발생해서 끝이 잘 나지 않은 이벤트가 발생했을 때 debounce를 적용한다면, 종료 지점을 알수가 없어 함수 실행이 어렵다.
하지만 throttle을 사용한다면 이벤트의 종료와 상관없이, 일정시간마다 함수를 호출하기에 효율적으로 함수를 실행할 수 있다.