Front-end/Nextjs

Next.js getServerSideProps, getStaticProps, getStaticPaths

아지송아지 2022. 5. 15. 18:06

안녕하세요!

오늘은 pre-rendering과 data fetching에 관련된 지식들을 알아보겠습니다.

 

 

Pre-rendering?


nextjs에서 가장 중요한 개념 중 하나인 Pre-rendering을 먼저 얘기해보겠습니다.

 

nextjs는 클라이언트 측에서  자바스크립트로 모든 작업을 실행하는 대신 각 페이지에 대한 HTML을 미리 생성하는데 이것이 pre-redering(사전 렌더링)입니다. 사전 렌더링을 하면 렌더링 성능과 SEO가 향상됩니다.

* 기본적으로 next.js는 모든 페이지를 사전 렌더링 합니다.

 

 

그림을 통해 더 자세히 알아보겠습니다.

 

 

 

Pre-rendering을 하지 않으면, 초기에는 렌더링이 되지 않았다가 자바스크립트가 로드되면 페이지 요소들이 채워집니다.

 

 

 

반면 Pre-rendering이 있다면 사전에 만들어진 HTML 파일을 보여주고 이후 자바스크립트가 로드되면 Hydration이 실행됩니다.

이 시점에서 <Link />와 같은 기능들이 시작합니다.

 

* Hydration이란, 브라우저가 모두 로드되었을 때 사용자와 상호작용할 수 있는 상태를 의미합니다.

 

 

 

 

Pre-rendering의 종류


Pre-rendering은 Static Generation과 Server-side Rendering 두 가지 종류가 있습니다.

이 둘의 차이점은 언제 HTML 파일이만들어지는가 입니다. 중요한 포인트는 "언제" 입니다.

 

Static Generation은 빌드 시점에서 HTML이 만들어집니다.

Server-side Rendering은 매 요청마다 HTML이 새롭게 만들어집니다.

 

좌측 : Static Generation  우측 : Server-side Rendering

 

Static Generation

사용자의 요청과는 별개로 미리 만들어두어도 괜찮다면 이 방법이 좋습니다.

한번 만들어지면 CDN을 통해 재사용하기 때문에 서버에서 매번 요청하는 것보다 빠릅니다. 

공식 문서에 나와있는 Static Generation 페이지 예시입니다.
* Marketing pages - 마케팅 페이지
* Blog posts - 블로그 포스트
* E-commerce product listings - 제품 목록
* Help and documentation - 도움말, 문서

 

 

Server-side Rendering

속도는 느릴 수 있지만, 매번 서버에 요청을 하여 렌더링 하기 때문에 해당 페이지는 항상 최신 상태를 유지합니다.

 

 

next.js는 data fetching에 있어 (데이터를 가져오는 데 있어) 예전에는 getInitialProps를 사용하였지만,

9.3 버전부터는getStaticProps, getStaticPaths, getServerSideProp 세 가지로 나뉘었습니다.

 

 

 

 

1. getStaticProps


빌드 시에만 서버에서 데이터를 가져와 html과 json 파일을 미리 만듭니다.

이후에 서버에서 데이터가 바뀌어도 다시 통신을 하지 않기 때문에 주의하셔야 합니다.

 

html, json 파일 모두 퍼포먼스 향상을 위해 CDN에 캐싱합니다.

 

사용법

const Detail = ({ data }) => {
  return <></>;
};

export async function getStaticProps(context) {
  const data = await fetch("--");
  return {
    props: { data }, // 페이지 컴포넌트에 props로 넘길 것
  };
}

export default Detail;

 

 

2. getStaticPaths


getStaticProps와 동일하게 빌드시에 서버에서 데이터를 받아옵니다.

차이점이 있다면 getStaticPaths는 Dynamic Routes 에서 사용됩니다.

 

 

사용법

// [id].js
const Detail = ({ data }) => {
  return <></>;
};

export async function getStaticPaths() {
  return {
    paths: [
      { params: { id: "100" } },
      { params: { id: "200" } },
      { params: { id: "300" } }
    ],
    fallback: true // false or 'blocking'
  };
}

export async function getStaticProps(context) {
  const data = await fetch("--");
  return {
    props: { data }, // 페이지 컴포넌트에 props로 넘길 것
  };
}

export default Detail;

 

getStaticProps와 반드시 같이 사용하며 getServerSideProps와는 같이 사용할 수 없습니다.

path로 설정된 경로들은 빌드시 미리 만들어집니다.

위 예시는 id값이 100, 200, 300인 페이지를 미리 생성합니다.

 

fallback이 false일 경우 path에서 설정하지 않은 경로들은 대응하지 않습니다. 즉 404페이지가 뜹니다.

fallback이 true일 경우에는 백그라운드에서 정적 파일로 htm과 json을 생성하여 pre-render목록에 추가합니다.

따라서 처음 페이지가 로드될 때는 느리며 이후부터는 빠르게 로드됩니다.

 

 

 

 

3. getServerSideProps


서버 측에서 프리렌더를 하여 반환 데이터를 getServerSideProps로 페이지에 전달합니다.

빌드와 상관없이 요청마다 서버에서 데이터를 가져옵니다.

 

서버에서 계속 데이터를 가져오기 때문에 정보들은 항상 최신 상태로 유지됩니다.

따라서 제품 상세 페이지, 관리자 페이지와 같은 곳들에서 사용됩니다.

 

사용법

const Detail = ({ data }) => {
  return <></>;
};

export async function getServerSideProps(context) {
  const data = await fetch("--");
  return {
    props: { data }, // 페이지 컴포넌트에 props로 넘길 것
  };
}

export default Detail;

 

return

위 코드에는 props만 반환하고 있지만 getServerSideProps는 세 가지의 반환 값을 가집니다.

  • props : 컴포넌트로 리턴할 값
  • redirect : 페이지 접속 시 지정한 경로로 리디렉션 시키기 위해 사용되는 값
    • { destination : string, permanent : boolean} 형태입니다.
    • status 코드가 필요하거나 변경해야 할 때는 permanent 대신 statusCode를 사용합니다.
  • notFound : boolean 값입니다. true일 경우 404 status와 에러 페이지를 보여줍니다.
    • 데이터 통신에 실패하였을 때 사용합니다.

 

context

context 객체를 인자로 받으며 아래 정보들을 담고 있습니다.

  • params: 다이나믹 라우트 페이지면 해당 데이터를 가져온다.
  • req: Request 정보
  • res: Response 정보
  • query: 쿼리 스트링
  • preview: preview mode 사용 유무
  • previewData: preview mode 사용 시 전달된 데이터
  • resolvedUrl: 짧은 URL
  • locale: 현재 locale 정보
  • locales: 지원되는 모든 locale 정보
  • defaultLocale: 기본 locale 정보

preview mode에 대한 지식은 아직 부족하여 공부를 더 하고 글을 올리겠습니다.

 

 

감사합니다.

 

참고 : 

https://nextjs.org/learn/basics/data-fetching/pre-rendering

https://nextjs.org/docs/basic-features/data-fetching/get-static-paths

 

 

 

'Front-end > Nextjs' 카테고리의 다른 글

Next.js 페이지 이동 Link, Router  (0) 2022.05.10
Next.js Dynamic Routes를 알아보자  (0) 2022.05.09
Next.js _app과 _document에 대하여  (0) 2022.05.09
Next.js 시작하기 (typescript)  (0) 2022.05.09
Next.js 특징 살펴보기  (0) 2022.05.05