배경
센디 인턴 첫 파일럿 프로젝트를 구현할 당시, 디바운싱 기법을 사용한 것에 대해 적어보고자 한다. 센디의 "용달 비용계산기"는 상차지에서 하차지로 가는 데에 드는 비용을 알려주는 서비스이므로, "주소지"를 사용자에게서 입력받아야 했다. 이때, 주소지를 입력받는 input 태그 아래에 [입력값과 연관된 제시어들]을 서버에서 가져와서 보여주어야 했다.
처음에는 단순하게 input의 value를 useState로 선언하고, state가 바뀔 때마다 api 요청을 날려서 데이터를 가져왔다. 이 상태로 구현해서 사수분에게 코드 리뷰를 받았는데, "state가 바뀔 때마다 요청을 날리면 자원 낭비일 수 있다. 디바운싱 기법에 대해 검색해봐라."고 해주셔서 디바운싱에 대해 알게 되었다.
디바운싱이란?
디바운싱에 대해 처음 들었는데, 알고보니 프론트엔드에서는 굉장히 일상적으로 사용되는 기법이었다. 그래서 이런 이론에 대해 직접 주절거리는 것보다는 구현한 사항에 대해서만 적으려고 한다.
간단하게는 "매우 빠르게 실행되는 함수에 대해 일정 시간 간격으로 이후에 실행되도록 제약을 거는 기법"이라고 할 수 있다. 사용자의 키보드 입력은 매우 빠르기 때문에 입력마다 api 요청을 날리는 것은 자원 낭비로 이어진다. 함수 실행 시 setInterval로 지연 시간을 걸고, 지연 시간 이내에 함수가 다시 실행되면 지연 시간을 초기화한다.
useDebounce.ts
import { useRef } from 'react';
export function useDebounce<F extends (...args: any[]) => unknown>(callback: F, delay: number) {
const debounceTimer = useRef<NodeJS.Timeout | null>(null);
const debouncedFunction = (...args: Parameters<F>) => {
if (debounceTimer.current) {
clearTimeout(debounceTimer.current);
}
debounceTimer.current = setTimeout(() => {
callback(...args);
}, delay);
};
return debouncedFunction;
}
- 입력으로 들어온 callback 함수에 delay만큼의 디바운싱을 적용한 함수를 반환한다!
Input.tsx
// 주소 요청 api 요청을 날리고 응답 데이터를 state로 저장하는 함수.
const requestArrivalJusoSuggestion = async (juso: string) => {
const res = await getJusoSuggestion(juso);
setArrivalSuggestions(res);
};
// 위 함수에 useDebounce 훅을 적용해서 디바운싱이 적용된 api 호출 함수를 만든다!
const debouncedRequestArrivalJusoSuggestion = useDebounce(requestArrivalJusoSuggestion, 300);
// 이제 input의 state가 바뀔 때마다 api 요청을 날리지 않고, 일정 시간 간격 이후에 요청을 날린다.
const handleArrivalChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
const newArrival = event.target.value;
setArrival(newArrival);
if (newArrival === '') {
setArrivalSuggestions([]);
return;
}
debouncedRequestArrivalJusoSuggestion(newArrival);
};
Performance 체크
디바운싱을 적용하기 전과 후를 Performance 체크를 해보니, api 호출 회수와 그에 따른 리렌더링 회수가 눈에 띄게 줄어든 것을 확인할 수 있었다.
새로운 것을 알게 되서 재밌다.
'커리어 > Sendy' 카테고리의 다른 글
[센디] 20240321 일지 (0) | 2024.03.22 |
---|---|
[센디] 20240320 일지 (0) | 2024.03.21 |
[센디] 겨울방학 현장실습 회고 (2) | 2024.03.11 |
[센디] 인턴 6월까지 연장 (0) | 2024.03.01 |
[센디][인턴] 입사 후 첫 회고 (6) | 2024.01.15 |