Static Generation & Server-side Rendering

cansweep·2022년 7월 17일
0
post-thumbnail

Static Generation

If a page uses Static Generation, the page HTML is generated at build time. That means in production, the page HTML is generated when you run next build . This HTML will then be reused on each request. It can be cached by a CDN.

Static Generation을 사용할 경우 page의 HTML은 build time에 생성된다.
즉, next build 명령어를 실행했을 때 page의 HTML이 생성되는 것이다.
이렇게 생성된 HTML은 CDN에 캐시되며 요청이 있을 때마다 재사용된다.

Static Generation without data

function About() {
  return <div>About</div>
}

export default About

By default, Next.js pre-renders pages using Static Generation without fetching data.
Note that this page does not need to fetch any external data to be pre-rendered. In cases like this, Next.js generates a single HTML file per page during build time.

기본적으로 Next.js는 data를 가져오지 않고 Static Generation을 사용하여 페이지를 사전 렌더링한다.

위 예제의 경우 사전 렌더링되어야 할 외부 data가 필요하지 않은 페이지이다.
이러한 페이지들에 대해 Next.js는 build time에 각 페이지 당 하나의 HTML 파일을 만든다.

Static Generation with data

Some pages require fetching external data for pre-rendering. There are two scenarios, and one or both might apply. In each case, you can use these functions that Next.js provides:
1. Your page content depends on external data: Use getStaticProps.
2. Your page paths depend on external data: Use getStaticPaths (usually in addition to getStaticProps).

몇 페이지들은 사전 렌더링해야 할 외부 데이터를 필요로 한다.
이때 두 가지의 시나리오가 있는데 둘 중 하나만 사용될 수도, 두 가지 모두 사용될 수도 있다.

각 경우에 대해 사용자들은 Next.js가 제공하는 다음의 함수들을 사용할 수 있다.
1. getStaticProps : page 내용이 외부 데이터에 의존하는 경우
2. getStaticPaths : page의 경로가 외부 데이터에 의존하는 경우 (이 경우 getStaticProps를 추가로 사용할 수 있다.)

시나리오 1 : page의 내용이 외부 데이터에 의존하는 경우

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

export default Blog

page의 내용이 외부 데이터에 의존하는 경우를 예로 들자면 블로그의 게시글 목록을 나타낼 때가 있다.
이 경우 해당 page의 내용은 "블로그 게시글 목록"이라는 외부 데이터에 의존하게 된다.

function Blog({ posts }) {
  // Render posts...
}

// This function gets called at build time
export async function getStaticProps() {
  // Call an external API endpoint to get posts
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // By returning { props: { posts } }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      posts,
    },
  }
}

export default Blog

To fetch this data on pre-render, Next.js allows you to export an async function called getStaticProps from the same file. This function gets called at build time and lets you pass fetched data to the page's props on pre-render.

사전 렌더링 시 데이터를 가져오기 위해 Next.js는 getStaticProps라는 함수를 제공한다.
getStaticProps는 build time에 호출되며 가져온 데이터를 사전 렌더링할 때 page에 props로 전달할 수 있다.

시나리오 2 : page의 경로가 외부 데이터에 의존하는 경우

Next.js allows you to create pages with dynamic routes. For example, you can create a file called pages/posts/[id].js to show a single blog post based on id. This will allow you to show a blog post with id: 1 when you access posts/1.
However, which id you want to pre-render at build time might depend on external data.

Next.js는 dynamic routes를 지원한다.

예를 들어 id로 구분되는 각 블로그 글의 경로를 지정하고 싶다면 pages/posts/[id].js와 같이 생성할 수 있다.
이 경우 id가 1인 글이라면 post/1을 통해 해당 글 페이지에 접근할 수 있다.

그러나 build time에 사전 렌더링하고자 하는 id가 외부 데이터에 의존할 수도 있다.

Example: suppose that you've only added one blog post (with id: 1) to the database. In this case, you'd only want to pre-render posts/1 at build time.
Later, you might add the second post with id: 2. Then you'd want to pre-render posts/2 as well.

id가 1인 블로그 글 하나만 데이터베이스에 추가했다고 가정해보자.
이 경우 post/1의 경로만 build time에 사전 렌더링되길 바랄 것이다.

나중에 id가 2인 블로그 글을 추가할 수도 있다.
그러면 동일하게 post/2의 경로에 대해서도 사전 렌더링되길 바랄 것이다.

// This function gets called at build time
export async function getStaticPaths() {
  // Call an external API endpoint to get posts
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // We'll pre-render only these paths at build time.
  // { fallback: false } means other routes should 404.
  return { paths, fallback: false }
}

So your page paths that are pre-rendered depend on external data. To handle this, Next.js lets you export an async function called getStaticPaths from a dynamic page (pages/posts/[id].js in this case). This function gets called at build time and lets you specify which paths you want to pre-render.

사전 렌더링 해야 할 page의 경로가 외부 데이터에 의존하는 경우 pages/posts/[id].js과 같은 dynamic routes page에 getStaticPaths 함수를 사용할 수 있다.
getStaticPaths는 build time에 호출되며 사전 렌더링할 경로를 지정할 수 있다.

Also in pages/posts/[id].js, you need to export getStaticProps so that you can fetch the data about the post with this id and use it to pre-render the page.

또한 이 페이지에 대해 getStaticPropsgetStaticPaths를 동시에 사용하는 것도 가능하다.

When should I use Static Generation?

We recommend using Static Generation (with and without data) whenever possible because your page can be built once and served by CDN, which makes it much faster than having a server render the page on every request.

Next.js에서는 가능한 한 Static Generation을 권장하고 있다.
왜냐하면 page를 한 번만 만들고 이후에는 CDN에서 가져올 수 있기 때문에 각 요청마다 페이지를 그리는 Server-side Rendering보다 훨씬 빠르다.

You should ask yourself: "Can I pre-render this page ahead of a user's request?" If the answer is yes, then you should choose Static Generation.

언제 Static Generation을 사용해야 하는지에 대해 궁금하다면 지금 이 페이지가 사용자의 요청에 앞서 사전 렌더링이 가능한지를 생각해보자.
대답이 "네!"라면 Static Generation을 사용해야 한다.

On the other hand, Static Generation is not a good idea if you cannot pre-render a page ahead of a user's request. Maybe your page shows frequently updated data, and the page content changes on every request.

반면 사용자의 요청 전에 페이지를 사전 렌더링할 수 없다면 Static Generation을 사용하는 것은 옳지 않을 수 있다.
페이지가 의존하는 데이터가 빈번히 업데이트 되거나 페이지 내용이 매 요청마다 변하는 경우가 위 경우에 해당한다.

In cases like this, you can do one of the following:

  • Use Static Generation with Client-side Rendering: You can skip pre-rendering some parts of a page and then use client-side JavaScript to populate them.
  • Use Server-Side Rendering: Next.js pre-renders a page on each request. It will be slower because the page cannot be cached by a CDN, but the pre-rendered page will always be up-to-date.

이 경우 두 가지의 해결책이 존재한다.

  • Static Generation을 Client-side Rendering과 함께 사용하기
    : 일부분은 사전 렌더링을 포기하고 Client-side Rendering을 사용한다.
  • Server-side Rendering 사용하기
    : Server-side Rendering은 각 요청마다 페이지를 사전 렌더링한다. CDN을 사용하지 않기 때문에 느려지지만 사전 렌더링된 페이지는 항상 최신 상태이다.

Server-side Rendering

If a page uses Server-side Rendering, the page HTML is generated on each request.
To use Server-side Rendering for a page, you need to export an async function called getServerSideProps. This function will be called by the server on every request.

SSR 또는 Dynamic Rendering이라고도 불리는 Server-side Rendering을 사용하게 되면 page의 HTML은 각 요청마다 생성된다.

Server-side Rendering을 사용하기 위해서는 getServerSideProps 함수를 사용한다.
getServerSideProps는 server에서 모든 요청에 대해 호출된다.

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

// This gets called on every request
export async function getServerSideProps() {
  // Fetch data from external API
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  // Pass data to the page via props
  return { props: { data } }
}

export default Page

For example, suppose that your page needs to pre-render frequently updated data (fetched from an external API). You can write getServerSideProps which fetches this data and passes it to Page like below:

자주 업데이트 되는 데이터에 의존하는 페이지를 사전 렌더링하는 경우 getServerSideProps 함수를 사용해 데이터를 props로 넘길 수 있다.

📎관련 링크

Next.js 공식문서 - Static Generation
Next.js 공식문서 - Server-side Rendering

profile
하고 싶은 건 다 해보자! 를 달고 사는 프론트엔드 개발자입니다.

0개의 댓글