0.TL;DR
- 검색 과정에서 지나치게 많은 api 호출이 일어나고 있었음
- 이에 Debounce를 사용해 0.5초간 추가적인 입력이 없다면 api 호출이 일어나도록 구현
- 하지만 비즈니스를 고려하지 못한 측면과 UX를 고려한 Loading UI를 구현하지 않아 아쉬움이 있음
1. Why?
"관리하당"에서 음식 등록을 위한 검색 기능을 구현할 때, useEffect로 값이 변경될 때 마다 api를 호출해 검색 하도록 구현하니, 지나치게 api 전송이 자주 일어나고 있었다.
예를 들어 "삼겹살"을 검색한다면
- ㅅ
- 사
- 삼
- 삼ㄱ
- 삼겨
- 삼겹
- 삼겺
- 삼겹사
- 삼겹살
삼겹살 한 번 검색하는데 api가 9번이나 전송되는 꼴이다. 또한 이 과정에서 검색 api가 실행되며 그 결과값을 나타내는 창이 9번이나 리랜더링이 일어나게 되니, 사용자 경험에서도 그닥 좋지 않을 것이다.
2. Debounce로 해결
이를 해결하기 위해 Debounce를 구현하여 입력이후 일정 시간 api 요청을 지연시키고, 그 시간동안 추가적인 입력이 없다면 변경되지 않는다면 그 때 api 요청을 보내도록 구현했다.
시간 조정은 나름대로 최적의 값을 찾아보기 위해서 관련 논문을 Riss에서 서치해보았지만 찾지 못했고, 차선책으로 구글링을 통해서 ux관련 사이트를 찾아보니 첫 시작값으로 0.5초를 부여하고 이후에 피드백을 통해 개선하는 방법을 제시하기에 우선은 0.5초로 지정했다.
useEffect(() => {
const fetchSearchFood = async () => {
const res = await searchFood(search);
if (!res.success) {
throw new Error('API 요청에 실패했습니다.');
}
setSearchResults(res.response);
};
const debounce = setTimeout(async () => {
if (search) {
await fetchSearchFood();
} else {
setSearchResults([]);
}
}, 500);
return () => {
clearTimeout(debounce);
};
}, [search]);
- search값이 바뀔때마다 useEffect가 실행된다.
- 이 때, 만약 기존의 debounce 함수가 실행되고 있었다면 정리 함수가 호출되어 타이머를 종료한다.
- debounce 함수가 실행되고, 0.5초를 기다린다.
- search가 변경되면 1번으로 되돌아간다.
- 0.5초가 지나면 FetchSearchFood 함수를 실행시켜서 결과 값을 가져온다.
위의 방식을 통해 불필요한 검색 요청을 최소화하고, 최신의 search값만 api요청에 사용함으로써 유저의 경험 개선과 성능 향상에 기여하였다.
3. 아쉬운 점
아쉬운 점
- Business
- debounce로 api 요청을 줄이는게 기업적 측면에서 얼마나 도움이 되는지 모른다. 서버측 부담을 줄여주는건 당연히 좋겠지만, 얼마나 부담이 되고 이걸로 얼마나 이득이 생기는걸까? 결국 추측에 불과하다...🥲
- 네이버나 구글의 경우에도 검색창에서 debounce를 사용하지만, 거의 체감이 되지 않을 정도로 짧게 사용하고 있었다. 그 근거를 알고싶어서 Riss 서치, 구글링, Chat GPT 등을 사용했지만 찾지못했다.
- UX
- debounce를 통해서 api요청을 지연 시키는 도중에도 결과값을 나타내는 창을 우선 띄워놓고 스켈레톤 UI를 보여줬다면 UX 측면에서 더 나았을 것 같다.
4. 래퍼런스
https://ux.stackexchange.com/questions/95336/how-long-should-the-debounce-timeout-be
'Project > 관리하당' 카테고리의 다른 글
코드리뷰로 클린하고 일관적인 프로덕트 만들기 (0) | 2023.11.30 |
---|---|
폴더구조의 Best Practice를 찾아서 (0) | 2023.11.30 |
무한스크롤을 통해서 UX 개선하기 / React-Native (0) | 2023.11.30 |