debounce 개념

Category
스터디 노드 React
Status
Published
Tags
Study
Description
Published
Slug

Debounce란?

Debounce짧은 시간에 여러 번 호출된 함수 중 마지막 함수 호출만 실행하도록 하는 기법.
이벤트가 연속적으로 발생할 때,
특정 시간이 지나서야(지정된 대기 시간 이후) 한 번만 실행되도록 조정함.

 

Debounce가 필요한 이유

사용자가 빠르게 이벤트(예: 키 입력, 스크롤, 버튼 클릭)를 발생시킬 때,
이벤트가 너무 자주 호출되어 성능이 저하되는 문제를 방지
 
  • 검색창 자동완성
    • 사용자가 키보드를 칠 때마다 서버 요청을 보내지 않고, 입력이 끝난 후 일정 시간(예: 300ms) 동안 입력이 없으면 요청을 보내도록
    •  
  • 스크롤 이벤트
    • 사용자가 스크롤할 때 너무 자주 호출되는 이벤트를 제한하여 성능을 최적화.

 

Debounce의 동작 원리

  1. 이벤트가 호출되면 지정된 시간만큼 대기
  1. 대기 시간이 지나기 전에 같은 이벤트가 발생하면, 대기 시간을 리셋하고 다시 기다림
  1. 대기 시간이 지나고 더 이상 이벤트가 발생하지 않으면, 마지막 이벤트를 실행

 

일반적인 사용 사례

사용자가 입력한 내용을 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
실행 시점
이벤트가 멈춘 후 실행
지정된 시간 간격마다 실행
사용 예시
검색창 자동완성, 텍스트 입력
무한 스크롤, 스크롤 위치 확인