들어가며
안녕하세요! 오늘은 프론트엔드 개발자라면 반드시 알아야 할 디바운스(Debounce)와 쓰로틀링(Throttling)에 대해 알아볼게요.
스크롤 이벤트나 검색 입력 등에서 성능 최적화가 필요하다면, 이 두 기법은 여러분의 강력한 무기가 될 거예요! 😊
디바운스와 쓰로틀링이 필요한 이유
먼저, 문제 상황을 한번 볼까요?
// 😱 이런 코드는 성능 저하의 지름길입니다!
window.addEventListener('scroll', () => {
// 스크롤할 때마다 실행되는 무거운 작업
doSomethingHeavy();
});
// 🤔 검색창에서도 문제가 발생해요
searchInput.addEventListener('input', () => {
// API 호출이 입력할 때마다 발생!
searchAPI(input.value);
});
디바운스(Debounce) 구현하기
디바운스는 마지막 호출 이후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 기법이에요.
// ✨ 깔끔한 디바운스 구현
function debounce(callback, delay) {
let timerId = null;
return (...args) => {
// 이전 타이머가 있다면 제거
if (timerId) clearTimeout(timerId);
// 새로운 타이머 설정
timerId = setTimeout(() => {
callback(...args);
}, delay);
};
}
// 🎯 실제 사용 예시
const searchInput = document.querySelector('#search');
const handleSearch = debounce((value) => {
console.log('API 호출:', value);
// 실제 API 호출 로직
}, 500);
searchInput.addEventListener('input', (e) => {
handleSearch(e.target.value);
});
쓰로틀링(Throttling) 구현하기
쓰로틀링은 정해진 시간 동안 최대 한 번만 실행되도록 하는 기법이에요.
// ✨ 깔끔한 쓰로틀링 구현
function throttle(callback, limit) {
let waiting = false;
return (...args) => {
if (!waiting) {
callback(...args);
waiting = true;
setTimeout(() => {
waiting = false;
}, limit);
}
};
}
// 🎯 실제 사용 예시
const handleScroll = throttle(() => {
console.log('스크롤 이벤트 처리!');
// 실제 스크롤 처리 로직
}, 300);
window.addEventListener('scroll', handleScroll);
실전 활용 사례
1. 실시간 검색 구현하기
// 🔍 사용자 경험을 고려한 실시간 검색
const searchWithDebounce = debounce(async (value) => {
try {
const results = await searchAPI(value);
updateSearchResults(results);
} catch (error) {
console.error('검색 중 오류 발생:', error);
}
}, 400); // 0.4초 대기
searchInput.addEventListener('input', (e) => {
// 입력 중임을 표시
showLoadingIndicator();
searchWithDebounce(e.target.value);
});
2. 무한 스크롤 구현하기
// 📜 부드러운 무한 스크롤
const handleInfiniteScroll = throttle(() => {
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 100) {
loadMoreContent();
}
}, 500); // 0.5초마다 최대 한 번 실행
window.addEventListener('scroll', handleInfiniteScroll);
3. 실시간 저장 기능
// 💾 자동 저장 기능
const autoSave = debounce(async (content) => {
try {
await saveToServer(content);
showSaveSuccess();
} catch (error) {
showSaveError();
}
}, 1000); // 마지막 입력 1초 후 저장
editor.addEventListener('input', (e) => {
showSavingIndicator();
autoSave(e.target.value);
});
🚨 주의사항과 팁
1. 클린업 함수 구현하기
function debouncedFunction() {
const debounced = debounce(() => {
// 로직
}, 300);
// 컴포넌트가 언마운트될 때 클린업이 필요해요!
return () => {
clearTimeout(debounced.timerId);
};
}
2. React에서 활용하기
// ⚛️ React Custom Hook으로 만들기
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(timer);
};
}, [value, delay]);
return debouncedValue;
}
성능 비교
// 📊 일반 이벤트 vs 최적화된 이벤트
// 처리된 이벤트 수 비교
let normalCount = 0;
let optimizedCount = 0;
// 일반 이벤트
window.addEventListener('scroll', () => normalCount++);
// 쓰로틀링 적용
window.addEventListener('scroll',
throttle(() => optimizedCount++, 100)
);
// 1분 후 결과 확인
setTimeout(() => {
console.log(`일반 이벤트 호출 수: ${normalCount}`);
console.log(`최적화된 호출 수: ${optimizedCount}`);
}, 60000);
마치며
디바운스와 쓰로틀링은 프론트엔드 최적화의 기본이면서도 강력한 도구예요.
상황에 맞게 적절히 활용한다면, 여러분의 애플리케이션은 훨씬 더 효율적이고
사용자 친화적으로 동작할 거예요! 😊
항상 기억하세요:
- 디바운스: 연이은 호출을 하나로 묶을 때 (예: 검색, 저장)
- 쓰로틀링: 일정 주기로 호출을 제한할 때 (예: 스크롤, 리사이즈)
즐거운 코딩 되세요! 🚀
'JavaScript' 카테고리의 다른 글
[npm/yarn] package.json 스크립트 명령어 예시 (0) | 2025.03.17 |
---|---|
[JavaScript] axios 인터셉터로 전역 에러 처리하기 (0) | 2025.03.17 |
[JavaScript] sort() 숫자 정렬 안되는 문제 해결법 - 숫자 정렬 / 비교 함수 (1) | 2022.09.30 |
[JavaScript] a 태그의 href="javascript:void(0)"는 무엇인가? - intent scheme (0) | 2022.09.26 |
[JavaScript] DateTime 을 AM/PM 포맷으로 변환하는 법 / AMPM 시간 변환 (0) | 2022.09.16 |