[Next.js]SSG,SSR, 사전 렌더링 함수

kimminjunnn·2025년 6월 16일

CS

목록 보기
32/34

사전 렌더링 함수

사전 렌더링(Pre-rendering)이란?

사전 렌더링이란, Next.js를 대표하는 기능 중 하나로, 브라우저의 요청에 대해 사전에 렌더링이 완료된 HTML을 응답하는 렌더링 방식을 말합니다.

즉, 사용자가 웹 페이지에 접근할 때 이미 HTML이 만들어져 있기 때문에
빠른 로딩 속도와 SEO(Search Engine Optimization)에 유리합니다.

Next.js는 두 가지 방식의 사전 렌더링을 지원합니다.

사전 렌더링 함수의 종류

차이점은 언제 html을 생성하는가 입니다.

1. Static Site Generation (정적 생성)

  • 페이지를 빌드 시점에 HTML로 생성하여 정적으로 제공합니다.
  • 모든 요청을 빌드한 html로 재사용합니다.
  • 정적 생성된 페이즈들은 cdn에 캐시형태로 저장됩니다.

Next는 최대한 이 정적 생성 방식을 사용하길 권고합니다.
왜냐하면 페이지가 빌드되어 CDN에 의해 제공이 되어 사용되는 것이 매번 페이지 요청하는 것보다 성능적으로 우수하기 때문입니다.

이런 정적 생성된 페이지는 서버에서 데이터를 자주 받아올 일이 없는 페이지(소개, 포스트ㅡ 각종 문서등)에 주로 사용됩니다. 반대로, 데이터의 업데이트가 많거나 사용자의 요청마다 매번 바뀌는 페이지라면 별로 좋은 선택이 아닐 것입니다.

그러나 몇몇의 페이지들에서 외부에서 데이터를 fetching 해오지 않으면, 렌더링이 안되는 경우가 있습니다. 예를 들어 파일 시스템에 접근하거나, 외부 API를 사용하거나, 데이터베이스에 쿼리를 날릴 때입니다. 넥스트는 이러한 경우(데이터를 사용한 정적 생성)도 지원하고 있습니다.

이를 위해 사용하는 함수들

getStaticProps

  • 정적 생성 페이지에 데이터를 주입할 수 있도록 도와주는 함수입니다.
  • Next.js 코드에 getStaticProps가 있다면, 빌드 타임에 Next.js가 알아서 한 번 실행하며, 리턴한 props는 해당 페이지 컴포넌트에 전달됩니다.
  • 외부 API 호출, 로컬 파일 접근 등 서버에서 실행 가능한 작업을 수행할 수 있습니다.
기본 틀
export async function getStaticProps(context) {
  return {
    props: {},
  }
}
props 전달 예시
function BlogPost({ post }) {
  return (
    <div>
      <h1> {post.title} </h1>
      <div> {post.content} </div>
    </div>
  )
}

export async function getStaticProps() {
  const res = await fetch('https://.../posts/1')
  const post = await res.json()
  return {
    props: {
      post,
    }
  }
}

export default BlogPost

getStaticProps에서 데이터베이스로부터 id 값이 1인 해당 포스트 데이터를 불러오고, 그 post 데이터를 props로 리턴한다. 그러면 컴포넌트가 props를 통해 렌더링을 할 수 있게 됩니다.

getStaticPaths

만약 방금 예시에서 posts의 id값이 1뿐만 아니라 100개가 있고 각각 경로를 따로 설정해줘야 하는 경우에는 어떻게 해야할까요?
100개의 파일을 만들어줘야할까요?

당연히 아닙니다.

이런 경우에 getStaticPaths를 사용하여 데이터에 따라 사전 렌더링할 페이지의 동적 경로를 지정해주면 됩니다.

  • 즉 동적 라우팅([id].tsx 등)을 사용하는 페이지에서, 어떤 경로들을 미리 정적으로 생성할지 명시하는 함수입니다.
기본 틀
export async function getStaticPaths() {
  return {
    paths: [
      { params: { ... } }
    ],
    fallback: ...
  };
}

getStaticPathspathsgetStaticProps 로 리턴합니다.


/pages/posts/1.js
/pages/posts/2.js
...
/pages/posts/100.js
각각 생성할 필요 없이, pages/posts/[id].js 파일 하나로 모든 페이지를 생성할 수 있습니다.

function BlogPost({ post }) {
  return (
    <div>
      <h1> {post.title} </h1>
      <div> {post.content} </div>
    </div>
  )
}

export async function getStaticPaths() {
  const res = await fetch('http://.../posts')
  const posts = await res.json()
  
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
  
  return { paths, fallback: false }

}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()
  return {
    props: {
      post,
    }
  }
}

export default BlogPost

getStaticPaths 에서 /posts 에 저장된 모든 블로그 포스팅 데이터를 불러오고, id 값을 파라미터로 리턴합니다.
그러면 getStaticProps 에서는 각 path의 params 값을 받아 id를 통해 블로그 포스트를 불러오고, 그 post를 props로 컴포넌트에 전달합니다.

fallback은 getStaticPaths에서 반환하지 않은 경로에 대해
Next.js가 어떻게 처리할지를 결정하는 옵션입니다.

  • false : paths에 정의되지 않은 경로로 요청이 오면 404 페이지를 반환
  • true : 최초 요청 시 비어있는 fallback 페이지(로딩 상태)를 보여주고,(즉 개발자가 isFallback 체크해서 로딩 UI 만들어야 함)
    그 사이에 백그라운드에서 데이터를 받아 HTML을 생성
  • blocking : 첫 요청 시에는 페이지가 다 생성될 때까지 기다렸다가 한번에 보여줌, 서버 사이드 렌더링을 통해 HTML이 생성되기까지 기다리겠다는 의미.

이 함수들은 모두 Next.js의 pages/ 디렉토리 안의 페이지 컴포넌트에서만 사용 가능하다는 제약이 있습니다.

2. Server-side Rendering(서버 사이드 렌더링)

  • 페이지를 사용자의 요청 시마다 서버에서 HTML로 생성합니다.
  • 매 요청마다 서버가 HTML을 새로 렌더링하므로 항상 최신 데이터를 반영할 수 있습니다.
  • 정적 생성보다 느릴 수 있지만, 사용자 맞춤 데이터(로그인, 쿼리 등)에 적합합니다.

getServerSideProps

getServerSideProps는 SSG의 getStaticProps와 비슷하지만 SSR을 위한 함수입니다.
페이지를 사용자의 요청이 들어올 때마다 서버에서 HTML을 생성하도록 해줍니다.

getStaticProps 처럼 컴포넌트에 props를 넘겨준다는 공통점이 있지만, 빌드 시가 아닌 매 request마다 실행된다는 차이점이 있습니다.

기본 틀
export async function getServerSideProps(context) {
  // 서버 측에서 실행되는 로직
  // context.req, context.res 등 접근 가능
  
  return {
    props: {},
  }
}
동적 라우팅 예시
export async function getServerSideProps(context) {
  const { id } = context.params;

  const res = await fetch(`https://api.example.com/posts/${id}`);
  const post = await res.json();

  return {
    props: {
      post,
    },
  };
}
context 객체
속성설명
reqNode.js의 HTTP 요청 객체 (IncomingMessage)
resNode.js의 HTTP 응답 객체 (ServerResponse)
params동적 라우팅 페이지의 파라미터
queryURL 쿼리 스트링
resolvedUrl현재 요청된 경로
locale(i18n 설정 시) 현재 언어
previewData프리뷰 모드 관련 데이터

보통 일반적인 사용에서는 req.coockies로 인증 정보, 쿠키 등을 확인하고, res는 리다이렉트나 캐시 제어가 필요한 경우에 사용합니다.

profile
Frontend Engineers

0개의 댓글