본문 바로가기
배움 기록/Next.js

[Next.js] Pre-rendering과 Data Fetching

by dygreen 2023. 4. 16.
Next.js의 가장 중요한 개념 중 하나인
Pre-rendering과 Data Fetching에 대해 정리해보겠습니다
🎗

 

Next.js를 본격적으로 공부하기 전에, CSR과 SSR 개념을 공부하면서 Next.js에 대한 개념도 간단하게 블로그에 정리했었는데

이번 기회에 더 자세하게 정리해보고자 한다

 

 

 

📌 Pre-rendering (사전 렌더링)

  1. (JavaScript가 모든 작업을 수행하는 대신) Next.js는 각 페이지에 대한 HTML을 미리 렌더링한다.
  2. 생성된 각 HTML은 해당 페이지에 필요한 최소한의 JS 코드와 연결된다.
  3. 이후, 브라우저에서 페이지를 로드하면 해당 JS 코드가 실행되어 페이지가 완전한 인터랙티브 상태가 된다.

 

이 과정을 hydration(하이드레이션)이라고 한다.

→ Pre-rendering을 사용하면 성능과 SEO가 향상될 수 있다. 

 

✔︎ Next.js가 App을 static HTML로 미리 렌더링하여 JS 없이도 APP UI를 볼 수 있음
✔︎ React APP인 경우, 사전 렌더링이 없으므로 JS를 비활성화하면 APP을 볼 수 없다!

 

Next.js를 사용했을 때

 

Next.js를 사용하지 않았을 때

 

 

두 가지 형태의 Pre-rendering

  • *Static Generation(정적 생성)[권장] : build 시 HTML을 생성하는 Pre-rendering 방식. HTML이 Pre-rendering된 다음 각 요청에 재사용된다.
  • Server-side Rendering(서버측 렌더링) : 각 요청에 대해 HTML을 생성하는 Pre-rendering 방식.

 

* 각 페이지별로 사용할 Pre-rendering 방식을 선택할 수 있음 (ex. 대부분의 페이지에서는 Static Generation을 사용하고, 다른 페이지에서는 Server-side Rendering을 사용하여 hybrid Next.js App을 만들 수 있다.)

 

Static Generation

 

Server-side Rendering

Server-side Rendering은 페이지에 자주 업데이트 되는 데이터가 표시되고, 요청할 때마다 페이지 콘텐츠가 변경되는 경우 사용하면 좋다

 

 

최근에 회사에서 진행한 CMS 프로젝트가 Next.js를 사용하였는데

개발 모드에서 잘 실행되던 프로젝트를 build 해보니 에러가 발생했었다.

알고보니 Next.js는 Pre-rendering으로 미리 HTML을 생성해 놓고 있는데,

props로 넘긴 state들이 초기값이 없는 상태(=외부 api로 데이터를 세팅하는 구조이다)여서 JSX를 읽을 수 없어 나타난 에러였던 것이다. 이를 해결하기 위해 초기값을 세팅해주니 에러가 안나고 잘 build되는 결과를 볼 수 있었다.

 

공식 문서: "개발 모드(npm run dev)에서는 모든 요청에 대해 페이지가 미리 렌더링된다. 이는 Static Generation에도 적용되어 개발이 더 쉬워진다. 프로덕션 모드로 전환하면 Static Generation은 모든 요청이 아니라 build시 한 번만 수행된다."

 

 

📌 Data Fetching

1. getStaticProps() : SSG

Static Generation with Data using getStaticProps

외부 데이터를 가져오지 않으면 HTML을 렌더링할 수 없는 페이지의 경우 사용할 수 있는 기능이다.

Next.js에서 페이지 컴포넌트를 export할 때, getStaticProps라는 비동기 함수를 export 하면 된다.

 

이렇게 하면...

  • 프로덕션 환경에서 build 시점에 getStaticProps가 한 번만 실행되고
  • 함수 내에서 외부 데이터를 가져와서 페이지에 props로 보낼 수 있다.
  • 기본적으로 getStaticProps를 사용하면 Next.js에 "이 페이지는 데이터 종속성이 있으므로 build 시 이 페이지를 Pre-rendering 할 때 종속성을 먼저 해결하세요!"라고 말할 수 있다.
  • 참고: 개발 모드에서는 각 요청에 대해 getStaticProps가 실행된다.

 

Before use...

  • getStaticPropsServer-side에서 실행됨
  • query parameters나 HTTP headers와 같이 요청 시에만 사용할 수 있는 데이터는 사용할 수 없음
  • 페이지에서만 export할 수 있음 (파일에서는 내보낼 수 없다)
  • build 시점에 한 번만 발생하므로, 자주 업데이트 되거나 사용자 요청 시마다 변경되는 데이터에는 적합하지 않음 (=> Server-side Rendering 사용하기)
  • 블로그 포스트, 제품 목록, 도움말 및 문서 등의 페이지에 적합함

 

 

| 실제 사용 코드 (외부 API에서 데이터를 가져오는 경우)

export async function getSortedPostsData() {
  // Instead of the file system,
  // fetch post data from an external API endpoint
  const res = await fetch('..');
  return res.json();
}
import { getSortedPostsData } from '../lib/posts';

export async function getStaticProps() {
  const allPostsData = getSortedPostsData();
  return {
    props: {
      allPostsData,
    },
  };
}

export default function Home({ allPostsData }) {
  return (
    <Layout home>
      <section className={`${utilStyles.headingMd} ${utilStyles.padding1px}`}>
        <h2 className={utilStyles.headingLg}>Blog</h2>
        <ul className={utilStyles.list}>
          {allPostsData.map(({ id, date, title }) => (
            <li className={utilStyles.listItem} key={id}>
              {title}
              <br />
              {id}
              <br />
              {date}
            </li>
          ))}
        </ul>
      </section>
    </Layout>
  );
}

 

 

SSG 2가지 상황

- Page 의 내용물이 외부 데이터에 의존적인 상황 → getStaticProps 만 가지고도 가능

- Page Paths 까지 외부 데이터에 의존적인 상황 → getStaticPaths 도 함께 활용해야 가능

 


2. getServerSideProps() : SSR

export async function getServerSideProps(context) {
  return {
    props: {
      // props for your component
    },
  };
}
  • parameter (context)에는 요청 관련 파라미터들이 포함되어 있다.
  • 요청 시 데이터를 가져와야 하는 페이지를 미리 렌더링해야 하는 경우에만 사용해야 한다.
  • 서버가 모든 요청에 대해 결과를 계산해야 하기 때문에 getStaticProps보다 느리다.

 

 

출처 : 
https://nextjs.org/learn/basics/data-fetching

 

728x90

댓글