공부혜옹

NextJS 사전렌더링 1. SSG와 getStaticProps 본문

공부합시다/React

NextJS 사전렌더링 1. SSG와 getStaticProps

Blair06 2022. 10. 20. 18:29

React CSR VS NextJS SSR,SSG

React는 CSR(client side rendering)을 사용해 SPA를 구현한다. 이 경우엔 페이지 소스를 확인해보면 거의 텅텅 빈 html 파일과 js 파일을 담은 코드 한줄을 읽을 수 있는데 이와 같이 비어있는 코드 덕분에 SEO(검색엔진최적화)에서 어려움을 겪는다.

반면, NextJS는 SSR(Server side rendering), SSG을 사용한다. 첫페이지를 사전렌더링 해놓고 출력하기 때문에 꽉 차 있는 html 파일을 제공한다.

학부생 레벨에서의 토이프로젝트는 이와같은 사실이 상관 없을 수 있으나 기업단위의 서비스를 제공할 땐 사용자들에게 많이 노출되어야 하는점이 중요하기 때문에 SEO가 중요하다

따라서 요즘은 NextJs를 사용하는 서비스들이 많아지고 있다

CSR와 SSR의 동작방식 및 차이점은 아래 게시글에 포스팅되어있다

2022.08.14 - [공부합시다] - CSR VS SSR

SSR VS SSG

NextJS는 서버사이드 렌더링을 지원한다고 하지만 사실 디테일하게 2가지로 또 다시 나뉜다

SSR과 SSG, 이 두가지는 사전페이지를 생성하는 시점에 따라 나뉜다

생성시점에 따라 특징이 있기 때문에 적절한 상황에 맞춰서 렌더링 방식을 적용하면 된다

SSG(static generation)

빌드타임에 사전페이지가 준비된다. 배포되고 나면 구축된 페이지는 앱을 실행시키는 서버나 CDN을 통해 캐시에 저장된다. 그렇기 때문에 즉시 입력 요청이 실행 가능하다

  • CSR과 달리 페이지가 사전에 구축되어 가득한 html 페이지를 보낸다
  • SSG와 달리 페이지 준비를 빌드단계에서 한다

사용하면 좋을 상황

  • 화면상의 데이터가 잘 바뀌지 않는 정적인 페이지
  • 빌드타임에 미리 페이지가 완성되어있다보니 실행 속도가 비교적 빠르다. 빨리 화면을 보여줘야할 경우 사용

SSG 적용방법

1. getStaticProps

특수한 비동기 함수인 getStaticProps를 사용한다

이름이 getStaticProps인 만큼 함수가 하는일은 컴포넌트 실행전 props에 넘겨줄 데이터를 준비한다 따라서 return값은 항상 props가 들어있는 객체여야한다

pages 하위 폴더 내부에 컴포넌트가 존재해야하며, 함수의 이름은 무조건 getStaticProps로 명명해야 NextJS가 찾을 수 있다

특이한 점은, 보통 서버사이드에서 사용하는 코드 또한 해당함수로 실행 할 수 있다

함수 내부 코드는 클라이언트에 재전송되지 않음으로 클라이언트에서 확인할 수 없기 때문에 데이터 베이스 크레덴셜을 포함하고 있는 코드를 함수 내부에서 실행하는 예시도 존재한다

소스코드

import axios from "axios";
interface Iprops {
  products: [
    {
      userId: number;
      id: number;
      title: string;
      completed: boolean;
    }
  ];
}
const index = (props: Iprops) => {
  const { products } = props;
  return (
{products.map((product) => (

{product.title}

))}
  );
};

export async function getStaticProps() {
  const result = await axios.get("<https://jsonplaceholder.typicode.com/todos/>");

  return {
    props: {
      products: result.data,
    },
  };
}

실행결과

SSG방식의 문제점

  • 빌드시에 페이지를 생성하기 때문에 데이터가 변경되어도 반영하지 못한다

이와 같은 문제점을 해결하기 위해 ISR(Incremental Static Regeneration) 방식을 적용한다

ISR은 몇가지 option을 추가해주면 쉽게 적용 가능하다

ISR (Incremental Static Regeneration) 적용방법

기존에 있던 return 객체에 revalidtate 요소를 삽입한다

revalidate는 페이지가 마지막으로 생성된지 얼마의 시간이 지나면 다시 재생성할지를 결정하며 초단위의 숫자를 삽입한다

return {
    props: {
      products: result.data,
    },
**//요청이 들어왔을때 생성되어있던 페이지가 60초가 지난 상태라면 새로운 페이지를 생성하여 대체한다**
		**revalidtate: 60** 
  };

위 코드를 기준으로 만약 빌드 된지 30초쯤 다시 새로고침하여 페이지에 접근하면 이전에 생성되어있던 페이지가 실행된다

하지만 만약 1분 20초쯤 페이지에 접근하면 revalidate 시간을 초과하였기 때문에 그즉시 서버에서 새로운 페이지를 생성하여 실행한다

!주의점: 개발서버에서는 revalidate, ssg와 상관없이 계속 새로운 페이지를 생성해낸다

또 다른 return 객체의 요소?

  • notFound
    • boolean값을 가지며 true일경우 404page로 연결한다
    • getStaticProps함수 내부에서 데이터 fetching시 에러로 인해 데이터를 불러오지 못했을때 예외처리로 사용할 수 있다
return {
    props: {
      products: result.data,
    },
		revalidtate: 60 ,
		**notFound: true**
  };
  • redirect
    • destination 요소가 있는 객체를 가진다. 설정할 경우 해당 라우트로 연결된다
    • data내에 상품이 없는것이 아니라 아예 접근하기 어려운 경우 예외처리로 사용할 수 있다
return {
    props: {
      products: result.data,
    },
		revalidtate: 60 ,
		**redirect: {
			destination:'/'
		},**
  };

여기까지가 기본적인 SSG를 적용하는 방법이다 이후 포스팅에서 동적 페이지를 위한 getStaticPath, SSR을 위한 getServerSideProps를 공부해보도록하겠다

반응형
Comments