getInitialProps와 getServerSideProps 비교 정리
2021-10-11 오후 3:49:25
getInitialProps vs getServerSideProps
next.js로 ssr을 하기 위해 getInitialProps, getServerSideProps, getStaticProps 를 사용한다.
next.js 공식 문서에서 9.3버전 이후부터는 getStaticProps와 getServerSideProps를 사용하는 것을 더 권장하고 있다.
그렇다면 그 차이점과 이유에 대해서 정리 해보자.
getInitialProps
공식문서의 내용을 보면 getInitialProps를 사용할 때, 데이터 초기값을 미리 요청해 컴포넌트에 전달하여 서버 사이드 랜더링이 가능하다고 되어있다.
다음 예시와 같이 사용한다.
function Page({ stars }) { return <div>Next stars: {stars}</div> } Page.getInitialProps = async (ctx) => { const res = await fetch('https://api.github.com/repos/vercel/next.js') const json = await res.json() return { stars: json.stargazers_count } } export default Page
필요한 데이터는 페이지에서 Props형태로 전달 받아 바로 완성된 데이터를 사용 할 수 있다.
페이지가 처음 로드 되는 상황인 경우, getInitialProps는 기본적으로 서버 사이드에서 실행된다.
그리고 next/link
또는 next/router
를 통해 라우팅 될 경우, 클라이언트 사이드에서 실행된다.
getServerSideProps
getServerSideProps를 사용하는 방법은 getInitialProps와 크게 다르지 않다.
아래 예시는 getServerSideProps를 사용하는 기본 예시이다.
export async function getServerSideProps(context) { const res = await fetch(`https://...`) const data = await res.json() if (!data) { return { notFound: true, } } return { props: {}, // will be passed to the page component as props } }
NotFound에 true값을 주면 404응답을 받게된다.
getServerSideProps에서 사용하기 위한 모듈은 최상단에 import하여 사용 가능하다.
getServerSideProps에 사용된 모듈들은 클라이언트 측에 번들로 제공 되지 않는다.
즉, 이 영역에서는 서버 측 코드를 작성 할 수 있게 된다.
예를 들어 숨기고 싶은 api url 또는 파일 읽기, 데이터베이스 읽기 등이 포함된다.
getServerSideProps는 항상 페이지 내에 사용되는 데이터가 최신이어야 할 때 사용해야 한다.
매번 페이지가 요청 될때 마다 getServerSideProps를 통해 프리랜더링 과정이 일어나
Time to first Byte (TTFB) 가 getStaticProps보다 느리기 때문이다.
또, getServerSideProps는 추가 설정 없이는 결과가 CDN에 캐시되지 않는다는 점도 있다.
데이터를 미리 페이지에 그려야 하는 상황이 아니라면 클라이언트 사이드에서 데이터를 받아 오는 방식을 고려하는 것이 좋다.
차이점
getInitialProps는 next.js 공식문서에서 Automatic Static Optimization을 지원하지 않는다고 되어있다.
Automatic Static Optimization이란 getServerSideProps 또는 getInitialProps가 페이지 내에
없는 경우에 next.js가 알아서 해당 페이지는 빌드시 html로 만들어주어서
프로젝트 자체가 ssr과 static page가 둘다 제공되는 하이브리드 웹 앱이 될 수 있게 도와주는 것이다.
static html로 만들어진 페이지는 cdn을 통해 사용자에게 즉시 스트리밍 할 수 있는
장점을 가진다.
그런데 custom app 컴포넌트 내에서 getInitialProps를 사용할 경우 이 자동 최적화 기능이
off된다.
그 외에도 getInitialProps vs getServerSideProps라는 제목으로
next.js의 github discussions에서 다루어진 글이 있다. ( 링크 )
내용을 살펴본 결과
getInitialProps를 사용 할 경우 ssr은 가능하지만 해당 코드가 클라이언트에서도 실행 되어야 하는
상황이 존재 하기 때문에 코드가 브라우저에도 전달 되어야 하고,
해당 영역에서 사용한 모듈이 있으면 또 그만큼 번들 사이즈가 커지게 된다는 점이 있다고 한다.
getServerSideProps를 사용하게 되면 항상 서버 사이드에서만 실행되므로,
해당 영역이 브라우저로 전달될 필요가 없어서 번들 사이즈를 줄일 수 있다.
클라이언트 사이드에서 데이터 패칭을 해야 할 경우 페이지를 먼저 보여주고 스켈레톤 ui나 로딩 아이콘을
보여준 다음 가져온 데이터를 화면에 보여주는 방식을 권장 하는 듯 하다.
아무래도 서버 사이드에서만 실행되어야 숨기고 싶은 api url 또는 파일 읽기, 데이터베이스 읽기 등의
코드를 작성 할 수 있어서 클라이언트 사이드에서도 실행 가능한 getInitialProps의 애매한 포지션보다는
getServerSideProps를 권장하고 클라이언트 사이드에서의 데이터는 클라이언트에서 가져오고
로딩 중이라는 표시를 사용자에게 해주는 방향으로 가려는 의도로 보인다.
그러나 getInitialProps의 클라이언트 사이드 에서도 페이지가 완성된 채로 보여줄 수 있다는 점 또한,
서버 비용을 줄일 수 있다는 큰 이점이 있다. 이는 개발자가 상황에 따라 고려하여 사용해야 할 듯 하다.
하지만 next.js를 만든 vercel의 입장에서는 제대로 사용하지 못하는 개발자들 까지 케어하기 위해
getServerSideProps와 getStaticProps를 만들어 영역을 분리하지 않았을까 하는 생각이 든다.