프로젝트에서 사용자 어플리케이션을 개발하고 실제로 사용해보니 약간의 UX 문제를 발견했다.
바텀시트에서 월을 변경할 때마다 로딩 인디케이터가 나타나서 사용자 경험이 매끄럽지 않았던 것이다.
이번 포스팅을 통해, 어떤 문제였고 어떻게 해결했는지 아주 간단하게 소개해보려고 한다!
문제 상황은 다음과 같다.

바텀시트를 열고 월을 변경할 때마다 새로운 데이터를 불러오기 때문에 잠깐동안 로딩 인디케이터가 돌아가는 문제였다.
React Query를 사용하고 기본 캐싱 시간을 5분으로 설정해놨기 때문에 다음과 같이 동작하고 있었다.
동작 순서
1. 예약 페이지 접근
2. 현재 월 데이터 패치 (6월)
3. 바텀 시트 열기 (6월 데이터 저장되어있음)
4. 7월로 변경
5. 7월 데이터 API 요청
6. 인디케이터 발생
7. 7월 데이터 캐싱
8. 데이터가 변경되어 다시 Default 세팅인 6월로 이동
9. 8월로 이동 -> 1~8 과정 반복
매번 새로운 월로 이동할 때마다 로딩이 발생하니 UX가 정말 좋지 않았다..
찾아보니 React Query에서는 Prefetch 기능을 아주 간단하게 제공하고 있었다.
현재 월 데이터를 가져올 때 미리 전후 월 데이터도 함께 가져와서 캐시에 저장해두면, 사용자가 월을 변경해도 로딩 없이 바로 데이터를 보여줄 수 있다.
Sample Code
export const useGetReservationInfoApi = ({ popupId, yyyyMM }: GetReservationInfoRequest) => { const queryClient = useQueryClient(); const query = useQuery({ queryKey: ['reservationInfo', popupId, yyyyMM], queryFn: () => getReservationInfo({ popupId, yyyyMM }), staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000, refetchOnWindowFocus: false, refetchOnMount: false, }); useEffect(() => { if (query.data && !query.isLoading) { const currentDate = new Date(yyyyMM + '-01'); const nextMonth = new Date(currentDate); nextMonth.setMonth(nextMonth.getMonth() + 1); const nextYearMonth = `${nextMonth.getFullYear()}-${String(nextMonth.getMonth() + 1).padStart(2, '0')}`; const prevMonth = new Date(currentDate); prevMonth.setMonth(prevMonth.getMonth() - 1); const prevYearMonth = `${prevMonth.getFullYear()}-${String(prevMonth.getMonth() + 1).padStart(2, '0')}`; queryClient.prefetchQuery({ queryKey: ['reservationInfo', popupId, nextYearMonth], queryFn: () => getReservationInfo({ popupId, yyyyMM: nextYearMonth }), staleTime: 5 * 60 * 1000, }); queryClient.prefetchQuery({ queryKey: ['reservationInfo', popupId, prevYearMonth], queryFn: () => getReservationInfo({ popupId, yyyyMM: prevYearMonth }), staleTime: 5 * 60 * 1000, }); } }, [query.data, query.isLoading, popupId, yyyyMM, queryClient]); return { reservationInfo: query.data?.data, isLoading: query.isLoading, isError: query.isError, }; };
기존에는 useQuery만 있었지만, useEffect를 추가해서 데이터가 로드되면 prefetchQuery로 전후 월 데이터를 미리 가져오도록 수정했다.
사용자가 이전 달로 갈 수도 있고 다음 달로 갈 수도 있기 때문에, 현재 월 기준으로 ±1개월 데이터를 모두 prefetch하도록 했다.
결과는 다음과 같이 로딩 없이 매끄럽게 동작하는 모습을 확인할 수 있었다.

간단한 UX 개선이었지만 사용자 입장에서는 체감되는 차이가 꽤 컸다.
사용자가 다음에 할 행동을 예측해서 미리 데이터를 준비해두면, 마치 데이터가 이미 있었던 것처럼 즉시 보여줄 수 있다.
물론 불필요한 API 호출이 늘어날 수 있으니 적절히 사용하는 것이 중요하겠지만, 이번 경우처럼 사용자가 높은 확률로 접근할 데이터라면 충분히 활용할 만한 기능이라고 생각한다!