scroll, resize, input, mousemove와 같은 이벤트는 짧은 시간 간격으로 연속해서 발생합니다.
이런한 이벤트에 바인딩된 이벤트 핸들러는 과도하게 호출되어 성능에 문제를 일으킬 수 있습니다.
Debounce와 Throttle은 짧은 시간 동안 연속해서 호출되는 이벤트 핸들러를 그룹화하여 과도한 호출을 방지하는 기법입니다.
짧은 시간 간격으로 이벤트가 연속해서 발생하면 이벤트 핸들러를 호출하지 않다가 일정 시간이 경과한 이후에 이벤트 핸들러가 한 번만 호출되도록 하는 것
핵심이 되는 debounce를 다시 한번 보겠습니다.
const debounce = (callback, delay) => {
let timerId;
return event => {
if (timerId) clearTimeout(timerId);
timerId = setTimeout(callback, delay, event);
}
};
timerId
가 존재하면, 즉 이미 함수가 호출된 상태라면 clearTimeout
을 통해 이전 호출을 취소합니다.
만약 timerId
가 존재하지 않는다면, 즉 함수가 호출된적이 없다면, setTimeout
을 통해 최초로 호출하게 됩니다.
눈치채셨겠지만, Debounce와 Throttle을 구현하는 데에 가장 중요한 개념은 클로저입니다.
debounce
는 호출되었을 때 중첩함수를 반환하는데, 이 중첩함수는 상위 스코프인 debounce
에서 선언된 timerId
를 참조할 수 있습니다.
짧은 시간 간격으로 이벤트가 연속으로 발생하더라도 일정 시간 간격으로 이벤트 핸들러가 최대 한번만 호출되도록 하는 것
const throttle = (callback, delay) => {
let timerId;
return event => {
if (timerId) return;
timerId = setTimeout(() => {
callback(event);
timerId = null;
}, delay);
}
debounce
와 마찬가지로 클로저를 이용하여 구현했습니다.debounce
와 차이점은, 이전에 호출된 이벤트 핸들러의 호출을 취소하느냐에 있습니다.debounce
는 이전 이벤트 핸들러 호출을 취소하고 새로 등록하지만, throttle
은 새로 이벤트 핸들러를 등록하지 않습니다.Leetcode에서 debounce, throttle 구현을 연습해 볼 수 있습니다.
다른 자바스크립트 개념에 대해서도 문제를 풀며 연습할 수 있습니다👍