Debounce란?
Debounce는 짧은 시간에 여러 번 호출된 함수 중 마지막 함수 호출만 실행하도록 하는 기법. 이벤트가 연속적으로 발생할 때,
특정 시간이 지나서야(지정된 대기 시간 이후) 한 번만 실행되도록 조정함.
Debounce가 필요한 이유
사용자가 빠르게 이벤트(예: 키 입력, 스크롤, 버튼 클릭)를 발생시킬 때,
이벤트가 너무 자주 호출되어 성능이 저하되는 문제를 방지
- 검색창 자동완성
- 사용자가 키보드를 칠 때마다 서버 요청을 보내지 않고, 입력이 끝난 후 일정 시간(예: 300ms) 동안 입력이 없으면 요청을 보내도록
- 스크롤 이벤트
- 사용자가 스크롤할 때 너무 자주 호출되는 이벤트를 제한하여 성능을 최적화.
Debounce의 동작 원리
- 이벤트가 호출되면 지정된 시간만큼 대기
- 대기 시간이 지나기 전에 같은 이벤트가 발생하면, 대기 시간을 리셋하고 다시 기다림
- 대기 시간이 지나고 더 이상 이벤트가 발생하지 않으면, 마지막 이벤트를 실행
일반적인 사용 사례
사용자가 입력한 내용을 300ms 후에 콘솔에 출력
import _ from 'lodash'; // Debounce된 함수 생성 (300ms 대기) const handleInput = _.debounce((inputValue) => { console.log('Input value:', inputValue); }, 300); // 키 입력 이벤트 document.getElementById('searchBox').addEventListener('input', (event) => { handleInput(event.target.value); // Debounce된 함수 호출 });
동작:
- 사용자가 검색창에
Hello를 입력한다고 가정: H→ 대기 300ms → 리셋He→ 대기 300ms → 리셋Hel→ 대기 300ms → 리셋- ...
Hello입력 후 300ms 동안 입력이 없으면 마지막 입력값Hello로 실행.
Debounce 직접 구현
Lodash 없이 순수 JavaScript로
debounce 구현function debounce(func, delay) { let timeoutId; // 현재 실행 대기 중인 타이머를 저장 return (...args) => { clearTimeout(timeoutId); // 이전에 설정된 타이머가 있으면 취소 timeoutId = setTimeout(() => { func(...args); // 지정된 시간이 지나면 실제 함수 실행 }, delay); // delay(ms) 만큼 대기 }; } // Debounce된 함수 생성 const handleResize = debounce(() => { console.log('Window resized!'); }, 500); // Window 크기 조절 이벤트에 연결 window.addEventListener('resize', handleResize);
동작
- 사용자가 창 크기를 조절할 때, 이벤트가 500ms 동안 중단된 후 한 번만 실행됨
React에서 사용
React에서 사용자가 입력한 검색어를 일정 시간 동안 입력이 멈춘 후 서버로 전송
import React, { useState, useEffect } from 'react'; import _ from 'lodash'; const SearchBar = () => { const [query, setQuery] = useState(''); const sendQueryToServer = (query) => { console.log('Sending query to server:', query); }; // Debounce된 함수 생성 const debouncedSearch = _.debounce((searchTerm) => { sendQueryToServer(searchTerm); // 서버에 검색어 전달 }, 300); useEffect(() => { // query가 변경될 때마다 debounce 호출 debouncedSearch(query); // cleanup 함수로 debounce된 호출 취소 return () => { debouncedSearch.cancel(); }; }, [query]); return ( <input type="text" placeholder="Search..." value={query} onChange={(e) => setQuery(e.target.value)} // 입력값 업데이트 /> ); }; export default SearchBar;
동작
- 사용자가
React라고 입력하면: R→ 대기 300ms → 리셋Re→ 대기 300ms → 리셋- ...
React입력 후 300ms 동안 입력이 없으면 서버로React전송.
Debounce vs Throttle
- Debounce: 이벤트가 멈춘 후에 마지막 호출만 실행.
- Throttle: 지정된 간격 동안 일정한 주기로 실행.
특징 | Debounce | Throttle |
실행 시점 | 이벤트가 멈춘 후 실행 | 지정된 시간 간격마다 실행 |
사용 예시 | 검색창 자동완성, 텍스트 입력 | 무한 스크롤, 스크롤 위치 확인 |