⚙️ [prefetching] 사용자 경험 어쩌구 증진 #개인 프로젝트(LOL) 리팩토링 #Next.js

간단한 프로젝트 소개

  • Riot API를 사용하여 롤 도감 사이트 제작
  • 챔피언 목록, 챔피언 상세 정보, 로테이션 정보, 아이템 정보 등을 확인할 수 있다. 
  • 사용기술: `Next.js`, `React`, `TypeScript` . . .

챔피언

  • 챔피언 목록 (+로테이션)
    • 전체 챔피언의 목록을 확인할 수 있다. (전체 목록, 역할군 별 목록)
  • 챔피언 상세
    • 챔피언의 상세 정보를 확인할 수 있다. (챔피언 정보, 스킬, 스킨 등)
  • 아이템 목록
    • 전체 아이템 목록을 볼 수 있다.
    • 특정 아이템을 선택하면 상세 정보, 상위 아이템, 하위 아이템을 확인할 수 있다.

챔피언 목록
챔피언 상세
아이템 정보
로테이션 목록


💡 Prefetching

사용자가 페이지로 이동했을 때 데이터를 불러오지 않고 특정 조건이나 로직등으로 미리 데이터를 불러올 수 있는 기법이다. 예를 들어 `<Link>` 태그가 뷰포트에 들어오는 시점에 미리 해당 페이지를 불러온다거나, `onMouseOver` 등의 이벤트가 실행되었을 경우 미리 상세 페이지의 데이터를 불러올 수 있다. 

 

⚙️ 로테이션 페이지 prefetching 적용

로테이션 페이지는 클라이언트 컴포넌트로 되어 있고, `React Query` 를 사용하여 데이터를 불러오도록 했다. 특정 이벤트나 조건 등으로 불러오지 않고, 메인 페이지에서 바로 prefetchQuery를 사용해 로테이션 페이지의 데이터를 미리 불러올 수 있도록 변경했다. 

 

📍 사용 방법

방법은 간단하다. 우선 데이터를 미리 불러올 컴포넌트에서 `prefetchQuery`를 사용한다. 그리고 로테이션 페이지에서 불러오는 데이터의 `queryKey`, `queryFn`을 똑같이 넣어주면 된다. 

 

1. QueryClient 인스턴스 생성

  const queryClient = new QueryClient({
    defaultOptions: {
	// ... 옵션들
    },
  });

QueryClient의 인스턴스를 prefetching할 컴포넌트에서 생성한다.

 

2. prefetchQuery

  await queryClient.prefetchQuery({
    queryKey: queryKey.champ.champs,
    queryFn: () => getChamps(),
  });
  • queryKey: 로테이션 페이지의 `useQuery` 에서 사용한 queryKey를 그대로 사용한다. 
  • queryFn: 마찬가지로 동일한 queryFn 사용

3. HydrationBoundary

<HydrationBoundary state={dehydrate(queryClient)}>
 {/* jsx 코드들 . . */}
</HydrationBoundary>

위 JSX(TSX)문법 그대로 `prefetching` 하는 컴포넌트에서 `HydrationBoundary`로 요소들을 감싼다. 

 

사용 방법은 끝


⚙️ 테스트 방법

`prefetching` 이 잘 되었는지 확인하려면 `React Query Devtools` 가 필요하다. 

 

💡 ReactQuery Devtools

 

설치

`npm i @tanstack/react-query-devtools`

 

적용

`ReactQueryProvider` 에서 `<ReactQueryDevtools/>` 만 추가해주면 된다.

 

// RQProvider.tsx 

// 기존
<QueryClientProvider client={queryClient}>
  {children}
</QueryClientProvider>

// 추가
<QueryClientProvider client={queryClient}>
  <ReactQueryDevtools /> // 이거 하나 추가됨
  {children}
</QueryClientProvider>

 

💡 테스트

위의 설정을 적용하고 브라우저로 돌아가면 귀여운 아이콘이 생겨있다.

누르면 뭐 나옴

 

위 아이콘을 누르면 React Query의 뭐 현황 같은걸 볼 수 있다. 

메인페이지임에도 내가 지정한 로테이션 페이지의 `queryKey` 에 해당하는 React Query가 생긴걸 볼 수 있다.

(각 queryKey를 눌러보면 데이터도 확인할 수 있다)

 

어쨋든 테스트도 해본 결과 적용이 잘 되었다. 


📍 변경 목적

변경한 이유는 크게 2가지가 있다. 

1. 사용자가 조금이라도 더 빠르게 데이터를 확인할 수 있도록 하기 위함

2. 코드를 줄이기 위함

 

1번은 아마 누구나 다 동의하겠지만 2번은 조금 의아할 수 있다. 정확히 말하자면 전체 코드의 총량은 더 늘었지만 로테이션 페이지, 그리고 앞으로 React Query를 사용할 실질적인(?) 컴포넌트에서의 코드는 줄었다. 이유는 다음과 같다. 

 

원래 `isPending`, `isLoading` 등으로 `fullfiled` 전에 로딩 UI 등을 리턴해주는 코드가 필요했다.

혹은 `initialData` 등을 활용해 UI 로직에서 에러가나지 않도록 처리를 해주어야한다.

 

하지만 메인페이지 등 한 군데에서 다 처리를 해주면 그 외의 컴포넌트에서는 뭔가 편하게 사용이 가능하지 않을까?

 

댓글

Designed by JB FACTORY