ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Next.js Pre-Rendering(Server-Side-Rendering) 함수 정리
    개발 블로깅/Next.js 2021. 4. 2. 15:05

     

     

    업무 시간에 시간이 붕 떠서,... Next.js Document를 정독했다..
    그래서 Doc 보면서 공부한 내용들을 블로그에 정리해보려고 한다.

    Hydration

    Next.js에서는 기본적으로 Page 별로 라우팅 처리가 되어 있다보니, 페이지 별로 데이터를 주고받는 등에 대한 association하기가 힘들수도 있으나, 이러한 점을 최소한의 자바스크립트 코드로 서로 연결을 해서 association이 가능하도록 한다. 그리고 브라우저에 의해 해당 페이지가 로드되면 이 연결되어있는 코드가 동작하면서 인터랙션이 가능하다.

    SPA에서 상태관리 라이브러리를 설정하는 것은 쉬우나, Next.js와 같은 환경에서는 추가 설정이 필요로 한데 이게 Hydration이 가능하도록 하기 위한 작업인 듯 하다.

     

    Pre-rendering

    Pre-rendering을 하는 방식에는 Static GenerationServer-Side-Renderin 두 가지 방식이 있는데, 이 둘의 차이점은 아래와 같다.

     

    • Static Generation: HTML 파일이 빌드 타임에 생성되서 각 요청에 의해 재사용 된다.
    • Server-Side-Rendering: HTML 파일이 각 요청이 올 때 생성 된다.

     

    Next.js Document에서는 우선 Static Generation을 사용하는 것을 권장하고 있는데, 그 이유는 Static Generation 방식이 추가 구성 요소 없이 CDN에 의해 고정적으로 페이지를 캐싱 처리를 할 수 있어서 일반 Server-Side-Rendering 보다 퍼포먼스 면으로 좋다고 한다.
    하지만 상황에 따라 Server-Side-Rendering만이 할 수 있는 요소도 있을 수도 있어서, Hybrid 형태로 사용 가능하다고 한다.

     

     

    getStaticProps

    Static Generationg할 때, 데이터도 미리 빌드 타임에 생성할 수 있다. 
    사용법은 해당 페이지의 같은 파일에 async getStaticProps 함수를 선언해서 export 하면 된다.

    // posts will be populated at build time by getStaticProps()
    function Blog({ posts }) {
      return (
        <ul>
          {posts.map((post) => (
            <li>{post.title}</li>
          ))}
        </ul>
      )
    }
    
    // This function gets called at build time on server-side.
    // It won't be called on client-side, so you can even do
    // direct database queries. See the "Technical details" section.
    export async function getStaticProps() {
      // Call an external API endpoint to get posts.
      // You can use any data fetching library
      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
    

     

    getStaticProps는 언제 사용해야할까?

    - user request 이전에, 빌드 타임 시에 미리 데이터를 불러오고자 할 떄.
    - 데이터는 CMS headless에서 온다. (이게 먼말이지...이따 찾아봐야겠다.)
    - 공용 캐싱 처리용도로 사용할 때.

    결론은, 그냥 해당 페이지에서 정적으로 사용되는 데이터들은 싸그리 getStaticProps에서 불러와서 사용하도록 하면 됨.
    다만 데이터 변경이 있다,(ex: 상품 리스트 등)는 사용하면 안된다. 

     

     

    getStaticPaths

    Next.js에서는 동적 라우팅 처리(ex: `pages/posts/[id].js`)가 가능한데, 이때 id로 들어갈 각 페이지 지정을 getStaticPaths에서 해줄 수 있다.

    // 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 }
    }
    

     

    함수를 보면, 모든 posts 데이터를 가져와서 각 포스트의 ID 값만 가진 paths 배열 데이터를 return한다. 예를 들어 `[{id:1},{id:2},{id:3}]`를 반환했으면, 동적으로 `pages/posts/1`, `pages/posts/2`, `pages/posts/3`페이지가  빌드 타임 때 생성된다.

    동적 라우팅 페이지 내에서도 당연히 getStaticProps 함수를 쓸 수 있다.

    function Post({ post }) {
      // Render post...
    }
    
    export async function getStaticPaths() {
      // ...
    }
    
    // This also gets called at build time
    export async function getStaticProps({ params }) {
      // params contains the post `id`.
      // If the route is like /posts/1, then params.id is 1
      const res = await fetch(`https://.../posts/${params.id}`)
      const post = await res.json()
    
      // Pass post data to the page via props
      return { props: { post } }
    }
    
    export default Post
    

     

     

    getServerSideProps

    빌드 타임 시 말고, 유저가 페이지 서비스에 접속하려고 페이지 요청을 보낼 시에 서버에서 정적 HTML 파일을 생성하는 방법이다.

    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

     

    사용법도 getStaticProps와 동일하고, 이름도 유사하지만, getServerSideProps는 빌드 타임 때가 아닌, 요청 시마다 동작하게된다.

     

     

    getInitialProps

    이 방식도 Server-Side-Rendering 방식인데, Automatic Static Optimization이 비활성화 되어서 권장하지 않는 방식이다.

    Automatic Static Optimization 이란?
    위에 설명했던 것 처럼, 미리 빌드 타임에 정적 파일로 생성되서 CDN 등으로 캐싱되서 요청 시 사용되는 방식을 말한다. 이로 인해 요청 시마다 항상 정적 파일을 생성하지 않고, 미리 생성되어 캐싱된 파일만 바로 제공하면 되므로 굉장히 빠른 로딩이 가능하다.

     

    만약 getServerSidePropsgetInitialProps를 페이지 내에 선언하게 되면, 해당 페이지가 요청 시마다 동작하게 되므로 Static Optimization이 되지 않는다는 점을 주의해야 한다.

     

    반응형

    댓글

Designed by Tistory.