프로젝트의 검색 기능 구현 중, 키워드를 입력할 때 마다 해당하는 많은 양의 데이터를 바로 목록에 뜨게 하려니 속도가 매우 느렸다. onChange이벤트나 스크롤 이벤트 등 한꺼번에 많은 이벤트를 처리해야할 경우 반드시 최적화가 필요하다.
검색할 때 키워드 목록을 보여주기 위해선 키워드를 입력할 때마다 API 요청을 해야 한다. "명수옹옹"을 검색하게 되면 총 4번의 API 요청을 해야하는데, 이는 매우 비효율적이다.
Debounce 란?
- 특정 이벤트가 발생할때 로직이 과도하게 발생하는 것을 방지하기위해 사용되는 함수이다.
- 마지막 이벤트가 호출된 이후, 일정시간이 지난 후에 해당 함수의 기능이 동작한다.
- 검색한 키워드에 해당하는 정보를 보여주는 기능 구현에 주로 사용한다.
일정 시간 후 코드를 비동기적으로 실행하는 함수인 setTimeout
를 사용하여 디바운스를 구현해 보았다.
const Search = () => {
const [user, setUser] = useState(false);
const [keyword, setKeyword] = useState('');
const searchUser = async (search) => {
// API 요청
// ... 생략
};
// 디바운스 구현
let timer;
const checkInp = (e) => {
const search = e.target.value;
if (timer) { // 200ms 전에 입력이 발생되면 이전 타이머 취소
clearTimeout(timer);
}
timer = setTimeout(() => {
if (search) {
searchUser(search);
setKeyword(search);
} else {
setUser('');
}
}, 200);
};
return (
<Wrap>
<HeaderBSU checkInp={checkInp} />
{user ? (
user.map((item) => <SearchUser props={item} keyword={keyword} />)
) : (
<SearchCont>
<img src={searchMain} alt="" />
<SearchMsg>유저를 검색해 팔로우 해보세요!</SearchMsg>
</SearchCont>
)}
<NavBar />
</Wrap>
);
};
200ms 안에 연속으로 들어온 이전 요청들은 clearTimeout(timer)
으로 clear되고 마지막 요청만 실행한다.
즉, 키워드를 검색하게 되면 일정 시간(200ms)이 지난 후 마지막 호출에서 검색 키워드에 대한 API를 요청하게 되므로 더 효율적으로 성능을 최적화할 수 있다.
Throttle 란?
- 이벤트를 일정 주기마다 한 번 발생하도록 하는 함수이다.
- 마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 한다.
- 무한 스크롤 기능 구현에 주로 사용한다.
디바운싱과 쓰로틀링은 성능을 목적으로 자바스크립트의 이벤트를 제어하기 위해 사용되는 기법이지만,
쓰로틀링은 X 밀리 초마다 정기적으로 기능 실행을 보장한다는 것이다.
디바운싱은 아무리 많은 이벤트가 발생해도 특정 시간 사이에 어떤 이벤트도 발생하지 않았을 때 딱 한번만 마지막 이벤트를 발생시킨다.