개발일지/React
[22] Debounce란? (Throttle의 차이)
꾸주니=^=
2024. 12. 21. 17:40
Debounce란?
Debounce(디바운스)는 연속적으로 호출되는 함수 실행을 제어하여, 특정 시간이 지난 후에만 함수가 실행되도록 만드는 기법입니다.
특정 작업이 불필요하게 자주 실행되는 것을 방지하고 성능을 최적화하는 데 사용됩니다.
Debounce의 동작 원리
- 이벤트가 발생하면 타이머가 설정됩니다.
- 설정된 시간 동안 이벤트가 다시 발생하지 않으면, 마지막 이벤트를 기준으로 설정된 시간이 지나 함수가 실행됩니다.
- 만약 타이머가 동작 중에 이벤트가 다시 발생하면, 기존 타이머가 초기화되고 다시 시작합니다.
언제 사용하나?
Debounce는 주로 사용자 입력 이벤트나 스크롤 이벤트 등에서 사용됩니다. 예를 들어:
- 검색 입력: 사용자가 입력할 때마다 API 요청을 보내는 대신, 입력이 멈춘 후에만 요청을 보냄.
- 창 크기 조정: 창 크기를 조정할 때 계산 작업을 과도하게 실행하지 않도록 함.
- 스크롤 이벤트: 스크롤 위치를 감지하는 작업을 최적화.
Debounce function은 사용자가 미리 결정된 시간 동안 타이핑을 멈출 때까지 keyup 이벤트의 처리를 지연시킨다.
이렇게 하면 UI 코드가 모든 이벤트를 처리할 필요가 없고 서버로 전송되는 API 호출 수도 크게 줄어든다.
입력된 모든 문자를 처리하면 성능이 저하되고 백엔드에 불필요한 로드가 추가될 수 있다.
Debounce의 구현
1. 기본 구현 (JavaScript)
function debounce(func, delay) {
let timer; // 타이머를 저장할 변수
return function (...args) {
// 기존 타이머가 있으면 초기화
if (timer) {
clearTimeout(timer);
}
// 새로운 타이머 설정
timer = setTimeout(() => {
func.apply(this, args); // 지정된 시간 후 함수 실행
}, delay);
};
}
사용법
function onResize() {
console.log('창 크기 변경!');
}
const debouncedResize = debounce(onResize, 300);
window.addEventListener('resize', debouncedResize);
- debounce(onResize, 300): onResize 함수가 호출되기 전, 마지막 이벤트로부터 300ms 동안 대기합니다.
2. Lodash의 _.debounce
Lodash는 JavaScript 유틸리티 라이브러리로, _.debounce를 제공하여 디바운싱을 쉽게 구현할 수 있습니다.
사용법
import _ from 'lodash';
function onSearch(query) {
console.log('검색어:', query);
}
const debouncedSearch = _.debounce(onSearch, 500);
// 사용 예시: 검색 입력 이벤트
document.getElementById('searchInput').addEventListener('input', (event) => {
debouncedSearch(event.target.value);
});
- _.debounce의 옵션:
- { leading: true }: 처음 호출 시 즉시 실행.
- { trailing: false }: 마지막 호출 이후 실행하지 않음.
3. React에서의 Debounce
React에서 디바운스는 주로 입력 필드와 같은 컴포넌트에서 사용자 입력이 멈춘 후에 상태를 업데이트하거나 API를 호출할 때 사용됩니다.
React에서 구현 예제
import React, { useState, useCallback } from 'react';
import _ from 'lodash';
function SearchInput() {
const [query, setQuery] = useState('');
// 디바운스된 함수 생성
const handleInputChange = useCallback(
_.debounce((value) => {
console.log('API 요청: ', value);
setQuery(value);
}, 500),
[]
);
return (
<input
type="text"
placeholder="검색어 입력"
onChange={(e) => handleInputChange(e.target.value)}
/>
);
}
export default SearchInput;
Debounce와 Throttle의 차이
특징 | Debounce | Throttle |
동작 방식 | 마지막 이벤트가 발생한 후 지정된 시간 후에 실행 | 일정한 간격으로 이벤트를 실행 |
사용 사례 | 검색 입력, 창 크기 조정 | 스크롤 이벤트, 버튼 클릭 방지 |
주요 목적 | 불필요한 호출을 최소화 (대기 후 실행) | 이벤트가 너무 자주 발생하지 않도록 제한 |
Throttle 예제
function throttle(func, delay) {
let lastCall = 0;
return function (...args) {
const now = new Date().getTime();
if (now - lastCall >= delay) {
lastCall = now;
func.apply(this, args);
}
};
}
Debounce의 장점
- 성능 최적화: 빈번하게 호출되는 함수를 제어하여 시스템 부하를 줄임.
- 자원 절약: API 호출 또는 DOM 업데이트를 효율적으로 관리.
- 코드 가독성 향상: 이벤트 처리 로직을 간소화.
실제 사용 사례
- 검색 입력 최적화:
- 사용자가 입력할 때마다 API 호출을 줄이고 마지막 입력 후 실행.
- 윈도우 리사이즈 최적화:
- 창 크기 변경 중 무거운 계산 작업을 방지.
- 폼 유효성 검사:
- 사용자가 입력을 멈춘 후 유효성을 검사.
요약
- Debounce는 지정된 시간 동안 이벤트를 모으고 마지막 이벤트 이후에만 실행합니다.
- 사용 사례: 입력 필드, 창 크기 조정, 스크롤 이벤트 등.
- React, Lodash 등을 활용하면 더 쉽고 효율적으로 구현할 수 있습니다.
- Throttle과는 다르게 마지막 이벤트 이후 실행된다는 점에서 차이가 있습니다.