본문 바로가기

공부/Next

[성능 최적화] Next.js HydrationBoundary를 활용한 서버-클라이언트 데이터 최적화

반응형

 

Next.js 서버 컴포넌트와 Tanstack Query를 활용해 성능 최적화하는 방법에 대해 소개해보려고 합니다.

서버 - 클라이언트 데이터 최적화   📖

Next.js의 서버 컴포넌트에서 데이터를 미리 패치해 클라이언트 컴포넌트로 넘겨준다면 초기 렌더링을 개선할 수 있습니다.


기존 코드

기존에는 클라이언트 컴포넌트에서 `Tanstack Query`를 사용해 데이터를 패칭을 했습니다.

const MainComponent = () => {
  const userId = useUserId();
  const { data: tourismList, isPending isError } = useGetTourismListQuery(userId);
  
  ...
}

 

 

리팩토링 코드

`HydrationBoundary``dehydrate`를 활용해 스탬프 페이지를 최적화한 코드입니다.

// layout.tsx

export default async function StampLayout({ children }: { children: React.ReactNode }) {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 1000
      }
    }
  });

  const user = await getUser();

  if (user) {
    await queryClient.prefetchQuery({
      queryKey: QUERY_KEY.STAMP_LIST(user.id),
      queryFn: () => getStampList(user.id)
    });
  }

  return (
    <HydrationBoundary state={dehydrate(queryClient)}>
      <MapProvider>{children}</MapProvider>
    </HydrationBoundary>
  );
}

 

핵심 코드 📖

1. 서버에서 데이터 미리 패치

const user = await getUser();

if (user) {
  await queryClient.prefetchQuery({
    queryKey: QUERY_KEY.STAMP_LIST(user.id),
    queryFn: () => getStampList(user.id)
  });
}

 

로그인한 사용자의 스탬프 데이터를 서버에서 `prefetchQuery`합니다. 이 데이터는 `queryClient`의 캐시에 저장됩니다.

 

2. 데이터 직렬화 

<HydrationBoundary state={dehydrate(queryClient)}>

 

`dehydrate`: Tanstack Query의 `queryClient`상태를 JSON으로 직렬화해 클라이언트로 전달합니다.

 

 

직렬화란 무엇이고 왜 필요한가

 

서버에서 데이터를 패치하고 Tanstack Query 캐시에 저장하더라도 클라이언트는 해당 데이터를 직접 접근할 수 없기 때문에 데이터를 전달하려면 JSON 형식으로 변환해야 합니다.

 

직렬화란 객체 형태를 문자열(JSON) 형식으로 변환하는 과정입니다. 

✅ 예시 코드

const data = { name: "Alice", age: 30 };
const serializedData = JSON.stringify(data); // '{"name":"Alice","age":30}'

 

✨ 간단하게 `queryClient`데이터를 JSON 형식으로 변환한다는 이야기입니다~!

 

3. 클라이언트에서 데이터 복원

<HydrationBoundary state={dehydrate(queryClient)}>

 

`HydrationBoudary`: Tanstack Query의 상태를 서버에서 클라이언트로 복원하는 데 사용되는 컴포넌트입니다.

 

그래서 클라이언트 컴포넌트에서는 새로 데이터를 패치하지 않고 바로 사용할 수 있습니다!

 

리팩토링 후 장점 📖

초기 렌더링 성능 향상

서버에서 미리 데이터를 준비하기 때문에 클라이언트에서 데이터를 기다릴 필요가 없습니다.

 

불필요한 API 요청 방지

서버와 클라이언트 간 데이터 공유로 동일 데이터를 중복 요청하지 않습니다.

 

회고 🧐

서버에서 데이터를 미리 패치해 클라이언트로 전달해 주는 과정에서 초기 렌더링 성능을 개선할 수 있었고 사용자 경험을 향상할 수 있었던 좋은 경험이었습니다!

 

반응형