1. 프로젝트 개요


최근 진행한 프로젝트에서 사용자의 여행지 취향을 분석하는 설문조사 페이지 개발을 맡았다. 이 페이지는 다양한 카테고리(자연 및 야외 활동, 문화 및 역사, 음식 및 식당 등)에 해당하는 랜덤 여행지를 사용자에게 제시하고, 그 중 마음에 드는 곳을 선택하도록 하는 방식으로 설계되었다.

실제 개발된 설문조사 페이지

실제 개발된 설문조사 페이지

2. 개발 과정 및 트러블 슈팅


:: 초기 구현과 직면한 문제점

설문조사 페이지는 11개의 서로 다른 카테고리에 대한 여행지 정보를 제공해야 했다. 초기 구현에서는 각 카테고리별 API 요청을 위해 개별 useQuery 훅을 사용했다:

// 초기 구현: 개별 useQuery 사용 (예시 코드)
const useNatureSpots = () => {
  return useQuery({
    queryKey: ['surveyList', categoryInfo['자연 및 야외 활동']],
    queryFn: getSurveyList,
    refetchOnWindowFocus: false,
  });
};

const useCulturalSpots = () => {
  return useQuery({
    queryKey: ['surveyList', categoryInfo['문화 및 역사']],
    queryFn: getSurveyList,
    refetchOnWindowFocus: false,
  });
};

// ... 다른 카테고리들에 대한 유사한 훅들

이 접근 방식에서 두 가지 주요 문제점이 발견되었다:

  1. 성능 이슈: 각 카테고리마다 개별적으로 API 요청이 발생하면서 네트워크 병목 현상이 발생했다. 특히 각 여행지마다 포함된 고해상도 이미지 데이터로 인해 페이지 로딩 시간이 눈에 띄게 길어졌다.
  2. 코드 중복: 모든 카테고리에 대해 유사한 쿼리 로직을 반복해서 작성해야 했다.

:: 해결 시도 1. useQueries를 활용한 병렬 데이터 요청

이러한 문제를 해결하기 위해 TanStack Query의 useQueries 훅으로 전환했다. 이 접근법은 모든 카테고리 데이터를 병렬로 요청할 수 있게 해주었다:

const surveyListQueriesResults = useQueries({
  queries: Object.values(categoryInfo).map((categoryId) => {
    return {
      queryKey: ['surveyList', categoryId],
      queryFn: getSurveyList,
      refetchOnWindowFocus: false,
      refetchOnMount: false,
    }
  }),
})