[Next.js] - preRendering의 두가지 방식 - 1 (Static Generation)

thisishwarang·2023년 7월 9일
0
post-thumbnail

기본적으로 Next.js는 동적 데이터가 없는 모든 페이지를 preRendering합니다.

즉, 미리 HTML을 만들어 주는 것이죠.

  • preRendering을 하지 않는 CSR에서는 페이지를 로드하면 빈화면이 보이다가 JS파일을 로드하여 페이지가 화면에 보인다면?
  • preRendering을 하는 SSR에서는 페이지를 로드하면 기존의 만들어 놓은 HTML이 보이고 여기에 JS파일을 로드하는 hydration을 통해 완전한 페이지가 됩니다.

그렇다면 preRendering을 어떻게 하는지 알아야 하는데 이에는 두가지 방법이 있습니다.
1. Static Generation
2. Server Side Rendering

이 두가지 방법을 페이지 별로 다르게 할 수 있답니다!

1. Static Generation

: 빌드타임에 미리 HTML을 생성해 두는 것.
(이때 페이지를 생성할 때 외부 데이터를 읽어올 수 있다!)

어떻게 구현하는가??

getStaticProps : 페이지가 preRendering 되어야 하는 페이지임을 next.js에 알려주는 매서드

원래 next.js는 기본적으로 페이지를 preRendering하지만 이후 next.js가 페이지를 preRendering하지 않는 방법을 사용할 때, 특정 페이지는 여전히 preRendering 되어야 함을 next.js에 알려주기 위해 사용

  • 모든 page 파일에 추가할 수 있고, export를 해야 합니다.
  • 빌드타임때 가장 먼저 실행됩니다
function HomePage(props) {
  const { products } = props;
  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>{product.title}</li>
      ))}
    </ul>
  );
}

export async function getStaticProps() {
  return {
    props: {
      products: [{"id": "p1", "title": "Product 1"}],
    },
  };
}
//반드시 return으로 {}를 내보내야함.

export default HomePage;
  • 위 코드에서 웹사이트의 메인페이지인 HomePage에 props를 받아오는데 이는 getStaticProps()에서 받아옵니다. 이는 빌드타임때 가장 먼저 getStaticProps 메서드가 실행되기 때문에 가능하죠. 이를 통해 preRendering 될 때 먼저 데이터를 패칭해올 수 있습니다.

❓ getStaticProps()는 next build, 즉 프로젝트를 빌드할 때 실행된다고 했는데 그럼 그 외의 실행될 때는 없을까??

있습니다. 바로 next.js에 증분 정적 생성(ISR) 이라는 내장 기능을 통해서 입니다.
즉, 페이지를 빌드할 때 정적으로 한 번만 생성하는 것이 아니라 배포가 된 후에도 재배포 없이 계속 업데이트 된다는 뜻입니다.

👽 ISR(Incremental Static Regeneration)

SSR을 통해 우리는 미리 생성된 HTML을 사용자에게 바로 제공할 수 있습니다. 하지만 정적인 방식을 통해 SSR을 구현한다면 페이지 내 변화한 데이터 내용을 업데이트 할 수 없습니다. 이를 가능하게 해주는 방법을 ISR이라고 합니다.

import fs from "fs/promises";
import path from "path";

function HomePage(props) {
  const { products } = props;
  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>{product.title}</li>
      ))}
    </ul>
  );
}

export async function getStaticProps() {
  const filePath = path.join(process.cwd(), "data", "dummy-backend.json");
  const jsonData = await fs.readFile(filePath);
  const data = JSON.parse(jsonData);

  return {
    props: {
      products: data.products,
    },
    revalidate: 60,
  };
}

export default HomePage;

위 코드에서 단 한 줄만으로 ISR을 가능하게 하였습니다.
바로 revalidate: 60 입니다.
본인이 원하는 만큼 숫자를 입력하여 몇초를 기준으로 데이터 페칭을 업데이트 할 것인지 지정하여 정적인 SSR 방식의 단점을 보완할 수 있습니다.


🤩 동적으로 생성되는 페이지를 preRendering 하려면?

그렇다면 동적으로 생성되는 페이지에서 preRendering은 어떻게 할 수 있을까요? 예를 들어 [pid].js 라는 동적으로 생성되는 파일이 존재할 때 next.js는 pid 자리에 어떤 값이 들어오는지 모릅니다. 해당 파일에 작성된 HTML코드는 똑같겠지만 pid값에 따라 다른 데이터가 들어오기 때문에 이러한 동적 생성 페이지에서 preRendering을 하기 위해서는 getStaticPaths 라는 메서드가 필요합니다.

getStaticPaths() : 동적 페이지의 어떤 인스턴스를 미리 생성할지 next.js에게 알려주는 메서드

  • paths, fallback 값을 전달할 수 있습니다.
export async function getStaticPaths() {
  return {
    paths: [
      { params: { pid: "p1" } },
      { params: { pid: "p2" } },
      { params: { pid: "p3" } },
    ],
    fallback: false, 
  };
}

paths : preRendering 되어야 할 페이지의 path 값을 알려줍니다.
fallback : preRendering 되어야 할 페이지가 많을 때 사용되는데, true, false, blocking 세가지 값으로 설정할 수 있습니다.

  • true : 사용자에게 빠르게 일단 화면을 보여주어 흰 화면을 보여주고 싶지 않을 때
  • blocking : 조금 늦어도 되니까 페이지가 모두 로드 된 화면을 보여주고 싶을 때 사용

0개의 댓글