Next.js의 렌더링: SSR과 SSG

김현중·2025년 3월 3일

연구소

목록 보기
13/34
post-thumbnail

Next.js의 렌더링 방식에는 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG)라는 두 가지 핵심 렌더링 방식이 존재합니다(물론 두 개 말고 더 있음). 이 두 전략은 웹 애플리케이션의 성능, SEO, 사용자 경험을 크게 향상시킬 수 있습니다.

🏃‍♀️서버 사이드 렌더링(SSR)

SSR은 페이지 요청이 들어올 때마다 페이지 요청이 들어올 때마다 서버에서 HTML, CSS, js 파일 및 데이터를 받아와서 페이지를 렌더링하는 방식입니다. Next.js에서는 getServerSideProps 함수를 사용해서 SSR을 구현합니다.


getServerSideProps의 역할과 작동 방식

getServerSideProps는 페이지 컴포넌트가 렌더링되기 전에 서버에서 실행되는 함수입니다. 이 함수는 다음과 같은 특징을 가집니다.

  1. 요청 시점에 실행: 사용자가 페이지를 요청할 때마다 실행됩니다.
  2. 서버 측에서만 실행: 클라이언트 코드(ex: window 객체)에 접근할 수 없습니다.
  3. 데이터를 미리 불러옴: 컴포넌트에 필요한 데이터를 미리 불러와 props로 전달합니다.
export const getServerSideProps = async (context) => {
    // API 호출, 데이터베이스 쿼리 등을 수행
    const data = await fetchSomeData();
 
    console.log('서버에서 실행됨'); // 브라우저에서 안보이고 서버 콘솔에 보임   
    return {
        props: {
            data,
        },
    };
};

export default function MyPage({ data }) {
    // data는 이미 서버에서 불러온 데이터
    return <div>{data}</div>;
}

Context 객체

그리고 getServerSideProps 함수는 context 매개변수를 통해 요청 정보에 접근할 수 있습니다.

export const getServerSideProps = async (context) => {
    // 쿼리 파라미터 접근
    const { q } = context.query;
    
    // 요청 헤더 접근
    const userAgent = context.req.headers['user-agent'];
    
    const results = await searchData(q);
    
    return {
        props: { results, userAgent },
    };
};

SSR의 장단점

  • 장점:

    • 항상 최신 데이터를 제공
    • 동적 콘텐츠에 최적화되어 있음
    • 초기 로딩 속도가 빨라 FCP에 좋음
    • js를 이용한 렌더링이 아니기 때문에 SEO에 최적화가 가능함
  • 단점:

    • 매 요청마다 서버에서 페이지를 렌더링하므로 서버 부하가 높음
    • 첫 페이지 로드 시간이 API 응답 속도에 의존적임


+ SSR 친구 CSR

CSR은 브라우저가 서버에 HTML과 js파일을 요청한 후 로드되면, 사용자의 상호작용에 따라 js를 이용해 동적으로 렌더링 시킵니다.

  • 장점:
    - 첫 로딩만 기다리면, 동적으로 빠르게 렌더링이 되기 때문에 UX가 좋음
    • 서버에게 요청하는 횟수가 적어 서버의 부담이 적음
  • 단점:
    - 모든 스크립트 파일이 로드될 때까지 기다려야 함
    • 리소스를 청크 단위로 묶어서 요청할 때만 다운받게 하는 방식으로 완화시킬 수 있지만 완벽히 해결할 수 없음
    • 검색 봇이 크롤링을 할 수 없어 SEO의 문제가 있음


🚶‍♀️정적 사이트 생성(SSG)

정적 사이트 생성은 빌드 시점에 페이지를 미리 생성하는 방식입니다. Next.js에서는 getStaticProps와 동적 경로의 경우 getStaticPaths를 통해 SSG를 구현합니다.

getStaticProps: 정적 페이지 데이터 불러오기

getStaticProps는 빌드 시점에 실행되어 페이지에 필요한 데이터를 가져옵니다.

export async function getStaticProps() {
  const posts = await fetchPosts();
  
  return {
    props: {
      posts,
    },
  };
}

export default function Blog({ posts }) {
  return (
    <div>
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

getStaticPaths: 동적 경로 처리하기

동적 경로(/posts/[id]와 같은 형태)를 사용하는 페이지에 SSG를 적용하려면 getStaticPaths 함수가 필요합니다.

export async function getStaticPaths() {
  // 빌드 시점에 생성할 경로 목록 가져오기
  const posts = await fetchPosts();
  
  // 각 포스트의 id로 경로 생성
  const paths = posts.map(post => ({
    params: { id: post.id.toString() }
  }));
  
  return {
    paths,
    fallback: false, // 지정되지 않은 경로는 404 반환
  };
}

export async function getStaticProps({ params }) {
  // params.id를 사용하여 특정 포스트 데이터 가져오기
  const post = await fetchPostById(params.id);
  
  return {
    props: { post },
  };
}

export default function Post({ post }) {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

fallback??

getStaticPaths의 fallback 옵션은 빌드 시점에 생성되지 않은 경로에 대한 처리 방식을 결정합니다.

1. fallback: false

빌드 시 지정한 경로만 접근 가능하고, 그 외의 경로는 404 페이지를 반환합니다.

return {
  paths: [/* 미리 생성할 경로들 */],
  fallback: false
};

2. fallback: 'blocking'

지정되지 않은 경로로 요청이 들어오면 SSR처럼 서버에서 페이지를 생성합니다. 생성이 완료된 후에야 페이지가 클라이언트에 전달됩니다.

return {
  paths: [/* 미리 생성할 경로들 */],
  fallback: 'blocking'
};

3. fallback: true

지정되지 않은 경로로 요청이 들어오면 먼저 HTML만 있는 페이지를 반환하고, 백그라운드에서 데이터를 가져와 페이지를 완성합니다.

return {
  paths: [/* 미리 생성할 경로들 */],
  fallback: true
};

isFallback

그리고 이 옵션을 사용할 때에는 useRouterrouter.isFallback을 활용하여 로딩 상태를 처리 할 수 있습니다.

if (router.isFallback) return "fallback 로딩중입니다.";

이렇게 로딩으로 한 번에 처리하지 않고 isFallback처리를 따로 하는 이유는
fallback이 완료되고나서도 진짜 오류가 발생해서 데이터를 불러오지 못할 경우에는 따로 표시를 하기 위해서입니다.

SSG의 장단점

  • 장점:

    • 매우 빠른 페이지 로드 속도(미리 생성된 HTML 파일 제공)
    • 서버 부하 감소(빌드 시점에만 페이지 생성)
    • CDN에 캐싱하여 배포 가능
  • 단점:

    • 자주 변경되는 데이터에는 적합하지 않음
    • 많은 동적 경로가 있는 경우 빌드 시간이 길어질 수 있음
    • 사용자별 맞춤형 콘텐츠에는 제한적
profile
박수 받는 사람이 되고 싶어서 항상 노력합니다.

0개의 댓글