[Next js] SSR, SSG, ISR 이해하기

안광의·2022년 6월 16일
3

Next js 이해하기

목록 보기
1/2
post-thumbnail

시작하며

현업에서 프론트엔드 개발자로 일한지 거의 3개월이 넘어가면서 그동안 사용한 Next js에 대해 정리해보려고 한다. 기존에 javaScript + React로 프로젝트를 진행했었고 현업에서는 typeScirpt + Next js를 주로 사용했는데 typeScirpt에 대해서는 블로깅을 했지만 Next js에 대해서는 따로 정리하지 않아서 기초적인 내용과 함께 개인 프로젝트인 Fake Search를 typeScirpt + Next js로 마이그레이션했던 과정을 정리할 예정이다.



들어가기 전

Next js는 React 기반의 프레임워크이다. React에 대해서 제대로 이해하고 있다면 Next js를 새롭게 배우는 것은 어렵지 않다. Next js를 접하기 전에는 새로운 스택을 배운다는 막막함이 있었는데 실제로 사용해보면 아무것도 아니라는 것을 알게 된다. React를 사용해서 프로젝트를 완성해봤다면 Next js는 하루 만에도 익힐 수 있기 때문에 걱정할 필요가 없다고 생각한다.

Next js란?

Next js React를 서버 사이드 렌더링(SSR)을 할 수 있게 해주는 프레임워크이다. SSR의 장점은 첫 렌더링 화면이 빠르고 SEO에 유리하므로 규모 있는 프로젝트나 검색에 노출이 필요한 서비스에서는 CSR보다는 SSR이 필수적이다. React만으로도 SSR이 가능하지만 Next js를 사용하면 훨씬 간단하게 구현이 가능하다.

SSR, SSG, ISR


위 이미지는 Next js 프로젝트를 빌드했을 때 콘솔에 출력되는 화면으로 프로젝트 내에 존재하는 page들을 확인할 수 있다. 서버 사이드 렌더링을 하기 위해서는 프로젝트 내에 필요한 각각의 페이지들을 서버가 알고 있어야 하고 이를 이해했다면 Next js의 사용법에 대해서 쉽게 이해할 수 있다.

// Next js로 변환한 프로젝트 src/pages 디렉토리 구조
src
└── pages
    ├── _app.tsx
    ├── index.tsx
    ├── naver.tsx
    ├── preview.tsx
    ├── search
    │   ├── [word].tsx
    │   └── index.tsx
    └── setting.tsx
        ├── auto-complete.tsx
        ├── search-data.tsx
        └── site.tsx

서버 사이드 렌더링을 하기 위해서는 유저가 접속할 페이지를 미리 알고 있어야 하는데 Next js는 생성해야 할 페이지를 src/pages의 폴더명과 파일명으로 구분한다. index.tsx 는 루트(/)경로에 해당하는 페이지이고 setting 폴더의 site.tsx가 /setting/site 경로에 해당하는 페이지인 것처럼 폴더명과 파일명 대로 해당하는 페이지를 나타낸다. [word]처럼 대괄호로 감싸져 있는 폴더나 파일명은 동적 라우팅을 할 수 있는 페이지로 '/search/word에 해당하는 동적인 경로'에 [word]에 해당하는 페이지가 렌더링되고 그 값은 컴포넌트에서 받아서 사용할 수 있다.

그밖에도 _app.tsx는 모든 페이지를 초기화하고 재설정할 수 있는 페이지, 404.tsx, 500.tsx가 각 에러가 발생했을 때 보여지는 페이지인 것처럼 Next js에 의해 미리 규칙이 정해진 이름을 가진 페이지들도 존재한다.


SSR

SSR은 CSR과 반대되는 개념으로 서버에서 페이지를 렌더링해서 클라이언트에 전달해주는 방식인데 Next js에서 SSG나 ISR과 구분되는 이유는 렌더링되는 시점 때문인데, SSR은 사용자가 요청할때 마다 그 시점에 페이지를 새롭게 렌더링한다. 그렇기 때문에 Fetching 해야하는 데이터가 빈번하게 변경될 때 사용된다.

export default function SSRPage({ dateTime }: SSRPageProps) {
  return (
    <main>
      <TimeSection dateTime={dateTime} />
    </main>
  );
}

export const getServerSideProps: GetServerSideProps = async () => {
  const res = await axios.get('https://worldtimeapi.org/api/ip');

  return {
    props: { dateTime: res.data.datetime },
  };
};

해당하는 파일에서 getServerSideProps 라는 이름의 함수를 export 하면 클라이언트해서 페이지를 요청할 때 getServerSideProps 함수가 실행되고 값을 SSRPage에 전달하여 렌더링한 후 클라이언트에 전달된다.


SSG

SSG는 Static Site Generation의 약자로 Next js에서 페이지를 생성할 때 기본으로 적용되는 설정이다. SSR과 다른 점은 클라이언트가 요청하는 시점이 아니라 빌드 시에 페이지를 미리 생성해놓는 것이다.

export default function SSGPage({ dateTime }: SSGPageProps) {
  return (
    <main>
      <TimeSection dateTime={dateTime} />
    </main>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const res = await axios.get('https://worldtimeapi.org/api/ip');

  return {
    props: { dateTime: res.data.datetime },
  };
};

별다른 설정 없이도 SSG가 생성되지만 Data Fetching이 필요한 경우에 getStaticProps라는 함수를 export 하고 함수 내에서 데이터를 받아서 리턴하면 빌드 시에 getStaticProps가 실행되고 리턴하는 값을 컴포넌트에서 받아서 페이지를 미리 렌더링하게 된다. 단, 빌드하는 시점에 페이지가 미리 생성되기 때문에 fetching 하는 데이터가 변경되더라도 다시 빌드하지 않는 이상 반영되지 않는다.

ISR

ISR은 Incremental Static Regeneration의 약자로 빌드 시점에 페이지를 렌더링 한 후, 설정한 시간 마다 페이지를 새로 렌더링한다. 즉, ISR로 구분했지만 사실 SSG에 포함되는 개념이라고 할 수 있다. SSG는 빌드 시에 페이지를 생성하기 때문에 fetching 하는 데이터가 변경되면 다시 빌드해야 하지만 ISR은 일정 시간마다 알아서 페이지를 업데이트 해준다.

export default function ISR20Page({ dateTime }: ISR20PageProps) {
  return (
    <main>
      <TimeSection dateTime={dateTime} />
    </main>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const res = await axios.get('https://worldtimeapi.org/api/ip');

  return {
    props: { dateTime: res.data.datetime },
    revalidate: 20,
  };
};

SSG와 동일하게 getStaticProps라는 함수에서 fetching 할 데이터를 객체 내의 props라는 key의 값으로 내보내고 revalidate의 값으로 숫자를 리턴하면 해당 숫자(초) 마다 페이지가 새로 렌더링 된다.



마치며

SSR, SSG, ISR에 대한 이해가 Next js의 핵심이고 개념을 이해했다면 실제 구현하는 과정은 어렵지 않았다. route나 link, head 설정 등이 React와 약간은 차이가 있지만 공식문서에 굉장히 친절하게 나와있기 때문에 생각보다 빠르게 배울 수 있었다. 결국은 React이기 때문에 Next js의 기능보다는 Hooks API를 사용할 일이 더 많았고 각각의 페이지를 분리해서 파일을 생성한다는 차이점이 있을 뿐이다.

참고문서

profile
개발자로 성장하기

0개의 댓글