debounce와 throttle은 연속된 사용자의 입력을 처리하는 기술 입니다. debounce는 특정 기간 내의 입력 중 가장 마지막 입력을 처리하고, throttle은 특정 기간 내에 입력이 한번 되면, 이후 받는 다른 입력들은 모두 무시합니다. 이를 통해 성능 최적화 혹은 연속 입력으로 인한 에러를 방지할 수 있습니다.
debounce, throttle로 연속 입력 관리하기 (with react)
목차
1. debounce란?
2. throttle이란?
3. debounce, throttle 구현하기
4. 구현된 코드로 보기
1. debounce란?
- 연속 이벤트 발생시, 일정한 시간 동안 이벤트가 연속으로 발생 할 시, 마지막 이벤트 발생에만 핸들러를 호출
- 주로 텍스트 입력, 스크롤 이벤트(새로운 데이터 호출)에 적용
- 불필요한 처리 혹은 네트워크 요청 방지
- ex) 사용자가 검색어를 입력할 때 검색 결과 업데이트
2. throttle이란?
- 일정한 주기로 이벤트 핸들러를 호출
- 일정 시간 동안 이벤트가 연속 발생하더라도, 맨 처음 한번만 핸들러를 호출하고, 다음 주기에 다시 실행 가능해짐
- 스크롤 위치에 따라 이벤트를 발생할 경우 사용
3. debounce, throttle 구현하기
- debounce 함수 작성
- setTimeout 조작을 위한 변수생성
- delay 시간 안에 새로운 입력이 들어오면 기존에 있던 setTimeout 실행 취소
- 새로운 setTimeout 등록
/utils/debounce.js
const debounce = (func, delay) => {
// setTimeout 조작을 위한 변수 생성
let timerId;
return (...args) => {
// delay 시간 안에 새로운 입력이 들어오면 기존에 있던 setTimeout 실행 취소
clearTimeout(timerId);
// 새로운 setTimeout 등록하기
timerId = setTimeout(() => {
func(...args);
}, delay);
};
};
export default debounce;
- throttle 함수 작성
- setTimeout 조작을 위한 변수 추가
- delay 시간 안에 새로운 입력이 들어오지 않았을 경우에만 실행, delay 기간 내일 경우 입력 무시
- delay 시간 이후에 setTimeout 변수 초기화 시켜서 재실행 가능하게끔 처리
// utils/throttle.js
const throttle = (func, delay) => {
// setTimeout 조작을 위한 변수 추가
let timerId;
return (...args) => {
// delay 시간 안에 새로운 입력이 들어오지 않았을 경우에만 실행, delay 기간 내일 경우 입력 무시
if (!timerId) {
timerId = setTimeout(() => {
func(...args);
// delay 시간 이후에 setTimeout 변수 초기화 시켜서 재실행 가능하게끔 처리
timerId = undefined;
}, delay);
}
};
};
export default throttle;
- debounce, throttle 적용하기
- 이벤트 핸들러 내부에서 debounce, throttle 사용 함수 정의하지 않도록 주의
- 핸들러 내부에서 해당 함수를 정의할 경우, setTimeout 자체가 여러개 생겨 동작 오류가 남
import { useState } from "react";
import "./App.css";
import debounce from "./assets/utils/debounce";
import throttle from "./assets/utils/throttle";
function App() {
const [search1, setSearch1] = useState("");
const [search2, setSearch2] = useState("");
// debounce 적용
const debounceSearch = debounce((value) => setSearch1(value), 1000);
// throttle 적용
const throttleSearch = throttle((value) => setSearch2(value), 1000);
// parameter 넣어주기
const handleDebounce = (e) => {
debounceSearch(e.target.value);
};
// parameter 넣어주기
const handleThrottle = (e) => {
throttleSearch(e.target.value);
};
return (
<div className="App">
<div className="title">{`< debounce 적용시켰을 때 (1초) >`}</div>
{/* input에 이벤트 적용 */}
<input onChange={handleDebounce}></input>
<div>{`현재 입력된 값은 ${search1} 입니다.`}</div>
<hr />
<div className="title">{`< throttle 적용시켰을 때 (1초) >`}</div>
{/* input에 이벤트 적용 */}
<input onChange={handleThrottle}></input>
<div>{`현재 입력된 값은 ${search2} 입니다.`}</div>
<div className="throttle"></div>
</div>
);
}
export default App;
4. 구현된 코드로 보기