JavaScript에서 Debounce vs Throttle (코드로 간단히 설명)
Source: Dev.to

JavaScript를 오래 사용하다 보면 이벤트가 너무 자주 발생하는 경우를 마주하게 됩니다—예를 들어, input은 키를 누를 때마다, scroll은 초당 수십 번, resize는 창을 드래그하는 동안 계속 발생합니다. 매 이벤트마다 무거운 로직을 실행하면 성능이 저하됩니다. 여기서 **디바운스(debounce)**와 **스로틀(throttle)**이 등장합니다.
디바운스 — 사용자가 멈춘 후에 실행
디바운스는 사용자가 이벤트 트리거를 멈출 때까지 지정된 시간만큼 기다렸다가 함수를 실행합니다.
흔히 쓰이는 경우
- 검색 입력
- 폼 검증
- 자동 저장
- 타이핑 중 API 호출
JavaScript 구현
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
사용 예시 (검색 입력)
const search = debounce((text) => {
console.log("Searching for:", text);
}, 500);
input.addEventListener("input", (e) => {
search(e.target.value);
});
어떻게 동작하나요?
- 각 키 입력마다 이전 타이머를 취소합니다.
- 새로운 타이머가 시작됩니다.
- 사용자가 계속 타이핑하면 함수는 실행되지 않습니다.
- 타이핑을 멈추면 함수가 한 번 실행됩니다.
스로틀 — 고정된 간격으로 실행
스로틀은 이벤트가 몇 번 발생하든 X 밀리초마다 최대 한 번 함수가 실행되도록 보장합니다.
흔히 쓰이는 경우
- 스크롤 이벤트
- 리사이즈 이벤트
- 드래그 & 드롭
- 버튼 스팸 방지
JavaScript 구현
function throttle(fn, limit) {
let isLocked = false;
return function (...args) {
if (isLocked) return;
fn(...args);
isLocked = true;
setTimeout(() => {
isLocked = false;
}, limit);
};
}
사용 예시 (스크롤)
const handleScroll = throttle(() => {
console.log("Scrolling...");
}, 1000);
window.addEventListener("scroll", handleScroll);
어떻게 동작하나요?
- 첫 번째 이벤트는 즉시 실행됩니다.
- 함수가 잠금 상태가 됩니다.
- 잠금 기간 동안 발생한 모든 이벤트는 무시됩니다.
- 제한 시간이 지나면 함수가 잠금 해제되어 다음 호출이 가능해집니다.
디바운스 vs 스로틀 (간단 비교)
| 특징 | 디바운스 | 스로틀 |
|---|---|---|
| 함수 실행 시점 | 사용자가 멈춘 후 | 고정된 간격마다 |
| 추가 이벤트 처리 | 취소됨 | 무시됨 |
| 실행 스타일 | 지연 실행 | 즉시 실행 |
| 적합한 상황 | 입력, 검색 | 스크롤, 리사이즈 |
기억하기 쉬운 방법
Debounce → clear + wait
Throttle → lock + release
마무리 생각
디바운스와 스로틀은 작은 유틸리티이지만 성능, 사용자 경험, API 효율성에 큰 차이를 만들어냅니다.
언제 어떤 것을 사용해야 하는지를 이해하면 더 나은, 반응성이 뛰어난 JavaScript 코드를 작성할 수 있습니다.
행복한 코딩 되세요!