(Next.js) Pre-rendering : Static Generation

yunsungyang-omc·2022년 5월 19일
0

Next.js

목록 보기
4/6


들어서며

Next.js의 Dynamic Routing은 react-router-dom을 사용하지 않고도 아주 아주 손쉽게 라우팅을 프로젝트에 적용할 수 있다. src 디렉토리에서 page 폴더에 js 파일만 넣어놓으면 알아서 라우팅되기 때문에 next.js를 입문하는 뉴비 개발자들에게 가장 널리 알려진 기능이기도 하다.

하지만 Dynamic Routing만 이용하기 위해 Next.js를 이용한다는 것은 Next.js의 본질을 제대로 이해하지 못한 것이다.

Next.js는 서버 사이드 랜더링을 구현하기 위함이지, 손쉽게 라우팅을 구현하기 위한 것이 아니다!
하여, 본 포스팅에서는 Next.js의 주요한 기능인 getStaticPropsgetServerSideProps에 대해 다뤄보려고 한다.

getStaticSideProps와 getServerSideProps

아주 짧게 요약하면, 이 두 가지 기능을 사용하는 이유는 PreRendering을 적용하기 위함이다.

PreRendering

프리랜더링이란 SSR(ServerSideProps)를 구현하는 Next.js의 가장 큰 특징이다. React로 구성된 웹/앱은 CSR(Client Side Rendering)방식을 사용한다. CSR은 초기 랜더링 시 자바스크립트 파일을 모두 로드해오기 때문에, 초기 렌더링의 사용자 경험이 SSR에 비해 좋지 못하다.

때문에 사용자 반응이 중요하고, 검색엔진 최적화(search engine optimization, SEO)가 중요한 도메인에서는 서버 사이드 랜더링이 줄 수 있는 이점이 중요하다.

SSR은 미리 서버에서 HTML파일을 랜더링해 클라이언트로 전송해주기 때문에 초기랜더링 속도가 빠르다. 하지만 매번 서버에 요청을 보내서 화면을 받아오기 때문에, 화면 깜빡임이 많아지는 단점 또한 존재한다.

여기서, 프리 랜더링이 빛을 발휘하게 된다. Next.js는 필요한 화면만큼을 렌더링하고 나머지는 차차 자바스크립트 파일을 받아와 클라이언트 측에 랜더링을 맡기는 절충의 형태를 가지고 있다.

보다 쉽게 표현하자면, 처음에는 SSR을 나중에는 CSR 방식을 사용한다는 것이다. 문자 그대로 이해하자! 미리 랜더링하는 것!

PreRendering 적용하기

Next.js는 프리랜더링을 위해 정적 생성 방식과 서버사이드 랜더링 방식을 제공하고, 각각의 경우에 따라 사용할 것을 권장하고 있다.

정적 생성방식 (Static Generation - getStaticProps)

정적 생성 방식은 페이지의 콘텐츠가 외부 데이터에 연동될 때 사용할 수 있는데, 대략 마케팅 페이지, 블로그 포스트, E-커머스의 상품 페이지, term 같은 정적 텍스트가 주가 되는 페이지를 랜더링할때 유용하게 사용할 수 있다.

내 경우에는 프로젝트에서 "규정"과 관련된 텍스트들을 랜더링할때 사용할 수 있었다.

import Term from "src/constants/terms/Term";
import { Grid } from "@mui/material";
import { serialize } from "next-mdx-remote/serialize";
import { MDXRemote } from "next-mdx-remote";

const ServiceTerms = ({ source }) => ( // <--- 이 부분을 주목하시라
  <Grid container direction="column" flexWrap="nowrap">
    <Grid container direction="row">
      <MDXRemote {...source} />
    </Grid>
  </Grid>
);

export async function getStaticProps() {
  // MDX text - can be from a local file, database, anywhere
  const source = serviceTerm;
  const mdxSource = await serialize(source);
  return { props: { source: mdxSource } };
}

export default ServiceTerms;

자주 바뀌지 않는 규정 텍스트 뭉치를 상수 폴더 안에서 보관하고 있었는데, 이에 대해 마크다운 문법까지 적용해 프리랜더링 하기 위해 Next.js의 공식문서에서 사용하기를 권장하고 있는 next-mdx-remote라이브러리를 사용했다.

mdxSource로 정의한 변수를 props의 벨류로 적용 후, 상단의 JSX 함수의 매개변수로 전달해주면 프리랜더링이 아주 간단하게 적용된다.

getStaticProps함수는 params를 받아 그에 해당하는 경로(path)도 받아오는데, 캐싱까지 지원되기 때문에 페이지를 이동할 때 굉장히 빠른 렌더링 속도를 보여준다. 만일 데이터를 적용할 필요없이 단순히, path만 얻고 싶다면, getStaticPath를 사용할 수 있다. 하지만 대게는, 경로 뿐만 아니라 이에 연동된 데이터까지 적용하기 때문에 주로 getStaticProps를 사용하게 될 것이다.

sample code

const SamplerPost ({ post}) => {
  ...
  
}
  
export async function getStaticPaths() {
  const res = await fetch('https://.../posts');
  const posts = await res.json();
  // 원하는 post로 구성된 paths를 pre rendering할 수 있다.  
  const paths = posts.map((post) => ({
    params: {id: post.id}
  }));
  // { fallback : false }는 이외 다른 경로를 404에러 처리한다는 것을 의미한다.
  return { paths, fallback: false }
}
 
export async function getStaticProps({params}) {
  const res = await fetch('https://.../popst/${params.id}');
  const post = await res.json();
  
  return { props: {post}}
}
  
export default SamplePost;

더 읽어보면 좋은 글

profile
안녕하세요 주니어 프론트엔드 개발자 양윤성입니다.

0개의 댓글