Next.js 의 pre-rendering(SSG, SSR, ISR)

Yunjjeong·2022년 9월 27일
0
post-thumbnail

Next.js 란?

Next.js는 React로 만드는 서버사이드 렌더링 프레임워크이다.

제공하는 여러가지 기능(hot reloading, automatic routing, single file components...)이 있지만 오늘은 Next.js의 pre-rendering과 Data fetching에 대해서 말하려고 한다 !

Pre-rendering 이란?

Next.js에서는 기본적으로 모든 페이지를 프리 렌더링 한다. 이 말은 Next.js가 모든 페이지에서 미리 HTML을 생성한다는 말이다.

이때의 HTML은 해당 페이지에 최소한으로 필요한 자바스크립트 코드와 연결되어있다. 페이지가 브라우저에 의해 로드될 때 자바스크립트 코드가 동작하고 페이지가 인터랙티브하게 동작된다. 이 과정을 Hydration(하이드레이션)이라고 한다.

일련의 과정으로 프리 렌더링을 수행하면 결과적으로 더 높은 성능의 SEO를 제공할 수 있다.

Pre-rendering의 종류

Static Site Generation(SSG)

  • 빌드 타임에 HTML이 생성되며 매 요청시 재사용 된다.

  • 정적으로 생성된 페이지들은 CDN에 캐시된다. 이 때문에 SSR 방식보다 훨씬 빠르다. (퍼포먼스를 이유로 Next.js도 꼭 필요한 상황이 아니라면 SSG를 권장한다.)

외부에서 데이터를 가져올(data fetching) 필요가 있는 경우에도 SSG 사용이 가능할까? 가능하다!

페이지 내용이 외부 데이터에 의존한다면? getStaticProps를 사용한다.

function Blog({ posts }) {
  // 포스트 목록
}

export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
  }
}

export default Blog

페이지의 경로가 외부 데이터에 의존한다면? getStaticPaths를 사용한다.

function Post({ post }) {
  // 포스트 내용
}

export async function getStaticPaths() {
  const res = await fetch('https://.../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 Post
  • SSG 사용이 적합한 경우

    • 마케팅 페이지
    • 블로그 포스트
    • 이커머스 상품 목록
  • SSG 사용이 적합하지 않은 경우

    • 사용자의 요청 전에 프리 렌더링 할 수 없는 페이지거나, 페이지의 변경이 빈번하고 페이지의 내용이 매 요청마가 변경되어야 하는 경우.

    • SSG 사용이 적합하지 않은 경우에는 CSR를 함께 사용하거나, SSR를 사용하는 것도 좋은 방안이다.


Server Side Rendering(SSR)

  • 매 요청마다 HTML이 생성된다.

  • getServerSideProps를 사용하여 서버 사이드 렌더링이 가능하다. (getStaticProps와 다르게 매 요청마다 실행된다.)

function Page({ data }) {
  // data
}

export async function getServerSideProps() {
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  return { props: { data } }
}

export default Page
  • Next.js에서는 실행속도 등 퍼포먼스를 이유로 가급적 SSG 사용을 권고하고 있으니 꼭 필요한 경우에 사용하면 좋겠다 😀

Incremental Static Regeneration

  • ISR 방식은 일정 주기마다 데이터의 최신 여부를 검사하고 업데이트된 데이터로 페이지를 다시 생성한다. 전체 사이트가 아닌 특정 페이지만 다시 빌드하면 되는 것이다!

  • getStaticPropsrevalidate라는 prop을 추가하여 사용 가능하다.

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

export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    revalidate: 10, 
  }
}

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

  return { paths, fallback: 'blocking' }
}

export default Blog

Client Side Rendering(CSR)

데이터를 프리렌더링 할 필요가 없다면 당연히 useEffect등을 통한 CSR도 가능하다.

유저 대시보드와 같은 프라이빗하고 유저에게 특화되어 SEO가 필요하지 않은 경우에는 SSG와 CSR를 사용하는 것을 추천한다!
공식 문서에서는 이런 경우에 자사에서 만든 data fetching hook인 SWR를 사용하는것을 추천하니 사용해보는 것도 좋을 것 같다. 😁

참고

profile
Studying FrontEnd Development

0개의 댓글