[Next js] SSR로 초기로딩속도 높이기 (성능개선)

임보라·2024년 11월 19일

Next.js

목록 보기
4/23

기능을 완성시키고 테스트하는중애 화면에 그려지는 속도가 너무 느려서 작동안되나..?싶을정도로 반영이 느린점을 개선해보려한다.

🖍️ CSR vs. SSR

CSR의 경우,
서버로부터 빈 HTML과 JavaScript 파일을 넘겨 받은 다음에 Query가 실행된다.
Markup > JS > Query

SSR의 경우.
서버에서 내용을 채워서 HTML을 보내줘야 하므로, Query는 Markup을 전달하기 전에 실행된다.
Query > JS > Markup

기존코드 (CSR방식)

import browserClient from '@/utils/supabase/client';

//앨범전체데이터 가져오기
export const getAlbumList = async (userId: string) => {
  const { data, error } = await browserClient.from('album').select('*').eq('user_id', userId);

  if (error) {
    console.error('포토앨범 리스트 가져오기 오류 :', error.message);
    throw new Error('포토앨범 리스트 데이터를 가져오는 중 오류가 발생했습니다.' + error.message);
  }
  return data;
};

수정코드(SSR방식)

//serverAction
'use server';

import { createClient } from '@/utils/supabase/server';
//앨범전체데이터 가져오기
export const getAlbumList = async (userId: string) => {
  const serverClient = createClient();

  const { data, error } = await serverClient.from('album').select('*').eq('user_id', userId);

  if (error) {
    console.error('포토앨범 리스트 가져오기 오류 :', error.message);
    throw new Error('포토앨범 리스트 데이터를 가져오는 중 오류가 발생했습니다.' + error.message);
  }
  return data;
};

앨범데이터를 서버에서 가져옴 -> 캐싱, 상태관리 추가

  • staleTime(신선시간)
//useGetAlbumListQuery.tsx
export const useGetAlbumListQuery = (userId: string) => {
  return useQuery({
    queryKey: QUERY_KEY.ALBUM,
    queryFn: async () => {
      if (userId) {
        return await getAlbumList(userId);
      } else {
        return null;
      }
    },
    enabled: !!userId,
    staleTime: 60 * 1000 //데이터가 신선하게 유지되는 시간 (1분)
  });
};
  • HydrationBoundary
  • dehydrate
//page.tsx

const Album = async () => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 1000
      }
    }
  });

  const user = await getUser(); //유저아이디가져오는 훅으로 불러오기

  //프리패치
  if (user) {
    await queryClient.prefetchQuery({
      queryKey: QUERY_KEY.ALBUM,
      queryFn: () => getAlbumList(user.id)
    });
  }

  return (
    <HydrationBoundary state={dehydrate(queryClient)}>
      <div className="lg:pt-[64px]">
        <AlbumList />
      </div>
    </HydrationBoundary>
  );
};

0개의 댓글