Next.js의 데이터패칭 방식: getStaticProps, getStaticPath, getServerSideProps은 언제 사용하는가?

te-ing·2022년 5월 31일
0

요약

  • Next.js의 데이터 패칭 방식은 getStaticProps, getStaticPath 와 getServerSideProps이 있다.
  • getStaticProps은 유저의 요청마다 fetch할 필요가 없는 고정된 내용의 페이지를 렌더링할 때,
  • getStaticPath는 어떤 페이지를 미리 Static으로 빌드할 지 정하는 api로, getStaticProps + 동적라우팅이 필요할 때 적합하다.
  • getServerSideProps는 자주 변경되는 페이지로, 페이지를 렌더링하기전에 반드시 fetch해야 할 데이터가 있을 때 사용한다. 성능이 매우 떨어지기 때문에 꼭 필요한 곳에만 사용한다.

NEXT.js를 처음 사용하다보니 페이지를 구성하는 데에도 조심스러움이 있었다. 잘못된 방식으로 페이지를 생성하여 SEO가 어려워지거나 성능이 떨어지면 어떡하지? 하는 걱정이었다. 다른 팀원들이 작업한 페이지 중 [id]값을 통해 페이지를 구성한 방식을 보니 대부분 getServerSideProps를 사용하여 페이지를 구성하고 있었다.

이 방식을 작업물을 보여주는 페이지에서 사용해도 괜찮을까 하는 마음에 getServerSideProps 이 무엇인지, 그리고 이 방식을 사용해도 괜찮은지에 대해 공부해봤다.
어려웠던 내용이지만, 내가 이해한 것으로 요약하였고, 공부한 내용을 아래에 작성하였다.


getInitialProps 을 사용하지 않는 이유

만약 모든 페이지에 공통적인 데이터 패칭이 필요하다면 _app.tsx에서 전역적 데이터를 패칭해야 하는데, getInitialProps 이라는 기능을 사용한다. 하지만 이 방식을 사용하면 SSR 계산없이 페이지를 정적 HTML 으로 사전렌더링 해서 최적화를 하는 자동 정적 최적화(Automatic Static Optimization)가 비활성화되어 모든 페이지가 SSR을 통해 제공되게 된다.

때문에 Next.js 9.3버전 이후엔 이런 것을 방지하고자 SSR과 SSG를 분리해 Static Generation(정적 생성)인 getStaticProps, getStaticPath 와 getServerSideProps 로 나눠졌으며, 전역적인 데이터 패치 기능을 지원하지 않는다.

데이터 패칭방식

기본적으로 getInitialProps를 비롯한 데이터 패칭 메소드들은 리턴한 값을 해당 컴포넌트의 props로 보낸다. getinitialProps는 context를 기본 props로 받는데, 그 내부엔 ctx객체와 Component가 존재한다. Component는 해당 컴포넌트를 의미하며, Component로 보내는 ctx 객체의 구성은 다음과 같다.

  • pathname - 현재 pathname /user?type=normal page 접속 시에는 /user
  • query - 현재 query를 object형태로 출력 /user?type=normal page 접속 시에는 {type: 'normal'}
  • asPath - 전체 path /user?type=normal page 접속 시에는 /user?type=normal
  • req - HTTP request object (server only)
  • res - HTTP response object (server only)
  • err - Error object if any error is encountered during the rendering

여기서 주의할점은

  1. getInitialProps 내부 로직은 서버에서 실행되기 때문에 Client에서만 가능한 로직은 피해야 한다. (Window, document 등)

  2. 한 페이지를 로드할 때, 하나의 getInitialProps 로직만 실행된다. 예를 들어 _app.js에 getInitialProps를 달아서 사용한다면 그 하부 페이지의 getInitialProps는 실행되지 않는다. -> 커스터마이징을 통해 따로 처리해줘야 한다.

이런 것들을 고려해보았을 때, 이렇게 _app.tsx를 건들여서 데이터 패칭을 하는 것은 모든 페이지에서 전역적으로 가져와야 하는 데이터가 일괄적일 때 이외엔 지양하는 편이 좋다는 것을 알 수 있다.

getStaticProps

"빌드 시에 딱 한 번"만 호출되고, 바로 static file로 빌드되어, 빌드 이후 수정이 불가능하다.

data를 빌드시에 미리 호출하여 정적으로 제공하기 때문에 페이지 렌더속도가 빠르다. 때문에 유저의 요청마다 fetch할 필요가 없는 고정된 내용의 페이지를 렌더링할 때 유리하다.

getStaticProps는 빌드 시 데이터를 가져오며 쿼리 매개변수 또는 HTTP 헤더와 같이 요청 시에만 사용할 수 있는 데이터는 사용할 수 없다.

getStaticProps는 revalidate이라는 옵션을 통해 주기적으로 데이터를 패칭하여 SSG와 SSR의 장점이 합쳐진 ISR을 구현할 수 있다.

getStaticPaths (Static Generation)

동적라우팅 + getStaticProps를 원할 때 사용한다. 페이지가 동적 라우팅을 쓰고 있고, getStaticProps를 쓰는 경우, getStaticPaths을 통해 빌드 타임 때 정적으로 렌더링할 경로를 설정해야 한다. 여기서 정의하지 않은 하위 경로는 접근해도 화면이 뜨지 않는다. 동적라우팅 할 때, 라우팅 되는 경우의 수를 하나하나 집어넣어야 한다.

getServerSideProps

getServerSideProps는 빌드와 상관없이, page가 요청받을때마다" 호출되어 pre-rendering한다.

SSR (Server Side Rendering) 개념으로 pre-render가 꼭 필요한 동적 데이터가 있는 page에 사용한다. 매 요청마다 호출되므로 성능은 getStaticProps에 뒤지지만, 내용을 언제든 동적으로 수정이 가능하다다.

따라서 getServerSideProps는 사용자 대시보드 페이지(내정보 페이지)에 적합하다. 대시보드는 사용자 고유의 개인 페이지이므로 SEO는 관련이 없으며 페이지를 미리 렌더링할 필요가 없으며, 데이터는 자주 업데이트되므로 요청 시간 데이터를 가져와야 한다.

Next.js는 getServerSideProps를 정말 필요할 때만 사용하라고 권고한다. CDN에 캐싱되지 않기 때문에 느리기 때문이다. 데이터를 미리 가져올 필요가 없다면 클라이언트 측에서 데이터를 가져오는 것도 고려해봐야 한다. (ex. 사용자 대시보드는 사용자별 비공개 페이지이므로 SEO와 관련 없으며 미리 렌더링할 필요가 없다.)

그 외 getServerSideProps의 작동방식의 특징으로는
getServerSideProps는 서버사이드에서만 실행되고, 절대로 브라우저에서 실행되지 않는다. getServerSideProps는 매 요청시 마다 실행되고, 그 결과에 따른 값을 props로 넘겨준 뒤 렌더링을 한다.



참고사이트: NEXT.js 공식문서 devstone Velog Next.js 100% 활용하기

profile
병아리 프론트엔드 개발자🐣

0개의 댓글