PROJECT RECORD
한국관광공사 Open API를 활용해 주변 여행지를 숏폼으로 탐색하는 서비스. 복잡한 슬라이드 상태와 초기 네트워크 비용을 함께 개선했습니다.
MY CONTRIBUTION
관광지 목록, 상세 정보, 이미지가 순차적으로 이어지는 Open API 구조에서 초기 화면에 너무 많은 요청과 이미지를 한 번에 보냈습니다. 결과적으로 첫 슬라이드를 보기 전까지 네트워크 대기가 길어졌습니다.
전체를 먼저 가져오는 방식 대신, useSuspenseInfiniteQuery로 페이지 단위 목록을 만들고 Swiper Virtual로 화면에 필요한 슬라이드만 렌더링했습니다. 현재 위치를 기준으로 다음 페이지를 미리 요청하고, 상세 이미지는 실제로 필요한 시점까지 지연했습니다.
const { data, fetchNextPage, hasNextPage } = useSuspenseInfiniteQuery({ queryKey: ['places', location], queryFn: ({ pageParam }) => getPlaces({ location, pageParam }), getNextPageParam: (lastPage) => lastPage.nextPage, }); const slides = data.pages.flatMap((page) => page.items); // 현재 슬라이드 근처에서 다음 페이지를 선행 요청하고, // 상세 이미지는 슬라이드가 필요해질 때 로드한다.
이전 페이지를 앞쪽에 추가하면 기존 슬라이드의 인덱스가 밀립니다. 이미지가 없는 관광지에서는 Swiper의 slidesUpdated 이벤트가 기대한 시점에 오지 않아, 오버레이가 해제되지 않는 경우도 있었습니다.
앞에 추가된 항목 수만큼 목표 인덱스를 보정하고, DOM 반영 직후 실행이 보장되는 useLayoutEffect에서 슬라이드 위치를 복구했습니다. 세션의 현재 슬라이드와 페이지 파라미터는 URL query로 옮겨 새로고침·공유·재진입에도 같은 지점을 되찾게 했습니다.
const restoredIndex = savedIndex + prependedItems.length; useLayoutEffect(() => { swiperRef.current?.slideTo(restoredIndex, 0); }, [restoredIndex]); // /places?slide-index=12&page-param=3 // 탐색 상태를 URL에서 다시 복원한다.