React는 그 자체로도 훌륭하지만, CSR에 의한 몇가지 한계점이 존재한다
초기 랜더링 후, 서버로부터 데이터를 패칭받기 전까지의 시간이 걸린다
pure React는 서버로부터 html을 받은 후, JS를 파싱하여 DOM을 조작함으로써 (혹은 요소들을 채워넣음으로써) 브라우저에 표시할 내용을 페인팅한다.
이때 문제점은, sideEffect를 관리하기 위한 useEffect의 처리가 몹시 늦어지는 경우이다.
일반적으로, 데이터 패칭을 하기까지의 시간동안 리엑트는 Loading 화면을 보여주는것이 통상적이다.
하지만, 만약 받아와야 하는 데이터가 상당히 크고 네트워크 혼잡으로 오래걸린다면 어떻게 될까?
그 시간이 늘어나면 늘어날수록 클라이언트가 페이지로부터 나가버릴 확률도 높아지게 된다.
또한 더불어, 위에서도 언급하였듯 Pure React에서 받아오는 html은 오로지 id="root"인 요소만 존재하는 문서이다.
이것은 useEffect로 해당 내용을 변경했다 하더라도 그것은 개인 유저의 브라우저상에서 변경되는 내용이지, 서버로부터 오는 내용이 아니다.
즉, SEO 입장에서는 디메리트가 발생할 수밖에 없다.
따라서 이러한 문제점을 Next.js는 pre-rendering이라는 개념으로 해결하고 있다
pre-rendering이란, 서버에서 미리 필요한 정적 페이지를 랜더링하여 클라이언트에 전송하는 것을 의미한다.
이 말인 즉슨, 클라이언트로부터 날아가는 데이터 html에는 웹 크롤러가 보았을 때에 필요한 요소들이 다 들어있는 문서이므로 노출이 늘어나게 된다.
또한, 정적 페이지를 받은 이후, interactive한 유저 활동이 필요하게 되는 경우가 있을것이다 (ex, 모달창 오픈)
interactive한 활동이란, 단도직입적으로 말해 javascript 코드가 필요한 영역을 말한다.
따라서, 이런 상호작용을 위해 Next.js는 페이지별로 청크화된 자바스크립트 파일을 필요에 따라 전송한다. (Hydrate)
따라서, pre-rendering을 통한 빠른 정적페이지 제공 + 코드 스플리팅을 통한 자바스크립트 파일의 분할
을 통해 pure react보다 많은 강점을 가지게 된다.
또한, Next.js는 각 페이지에 존재하는 모든 jsx객체를 이미 "pre-rendering" 한 상태로 대기한다.
그말인 즉슨, 일반적인 react 코드로 작성되어 있는 요소들이 이미 유저에게 보내지기 전 이미 document파일의 내용에 삽입된 채로 전달이 된다는 소리이다.
다시말해, 아래와 같이 하드코딩된 jsx 객체라 할지라도
이미 유저에게 전달되는 상황에서 응답에 포함된 내용은 필요한 요소들이 다 들어가있는 html이다.
위와 같은 하드코딩뿐만 아닌, 서버 차원에서 미리 데이터를 받아 pre-fetching을 통해 페이지를 구성해야 할 필요도 있을 것이다. 이때 사용되는 것이 getStaticProps와 getServerSideProps이다. (참고로, jsx의 프리 랜더링 전에 해당 함수가 먼저 호출되어 데이터를 가져온다)
위에서 언급했듯, Next.js는 pre-rendering기능을 통해 미리, html 파일을 작성해서 저장해두고 그것을 계속 제공할 수 있다.
이 말인 즉슨, 배포 전 Build 과정에서 이미 필요한 요소들이 다 완성된 상태로 배포가 된다는 의미이다.
따라서 유저가 페이지 요청을 할 경우, 서버는 이미 CDN이나 서버에 캐시형태로 저장된 pre-build 페이지를 그대로 제공하면 된다.
즉, 변화가 없는 페이지를 전달하게 된다
그리고 나서, interactive한 영역에 대해서는 js코드를 전송하면서 hydrate를 하는 것이다.
이때, 페이지 파일 내에서 export되는 async 함수, getStaticProps는 next.js에 의해 function component보다 우선하여 작동한다.
NOTE. 여기서 getStaticProps의 내부는 서버사이드에서 돌아가는 내용들을 사용해야 한다.
즉, Node.js에서 사용했던 고유영역인 file system과 같은 메서드들을 이 내부에서는 사용이 가능하다.
반대로 이야기한다면 이 함수 내부에서는 클라이언트 사이드에서 사용하는 내용들은 사용할 수 없다. 예를들어, window를 참조하는 행위가 불가능한것과 같다.
NOTE2. 이 함수는 서버에 전달되지 않는다. 즉, 다시말하자면 해당 함수의 실행은 오롯이 초기 빌드가 이루어 질 때 완료가 되고 더이상 사용되지 않기 떄문에, 만약 SPA형태로 추가적인 서버 요청을 통한 변경이 필요하다면 useEffect를 통해 클라이언트사이드에서 요청을 날리는 방식으로 해야한다.
NOTE3. 해당 함수는 반드시 props를 키로 하는 프로퍼티를 지닌 객체를 리턴해야 한다. 그 이유는 이 함수가 호출된 후 function component에 해당 테이터를 prop 형태로 전달하기 때문이다.
정확하게 이야기하면, 한번 build를 한 상태에서 (페이지가 생성된 상태) Next.js는 해당 파일들에 패칭되야하는 데이터의 변화를 체킹할 수 있다. (getStaticProps의)
즉, 생성된 페이지들을 게속 그대로 정적으로 사용하는 것이 아닌, revalidate 옵션을 통해 props에 전달되야 할 값을 비교해보고, 차이가 존재한다면 새로운 빌드페이지를 만들어 캐싱한 후 이것을 제공하는 방식을 택한다.
참고로, 해당 옵션은 production 모드에서만 의미가 있고, development 환경에서는 해당 옵션의 의미는 매 요청때마다 getStaticProps를 호출하라는 것과 같게 된다.
다시말하면, getStaticProps 함수는 build를 완료한 후에 저장된 static 파일들에 대해서, 클라이언트측에서 요청이 올 때마다 revlidate 옵션을 확인하여 기존의 시간보다 해당 시간초가 지났을 때, getStaticProps 함수를 호출하여 해당 정적 파일들의 내용물을 교체한 후 이것을 유저한테 전송한다
또한 getStaticprops에는 여러가지 옵션이 있다
1. notFound : 이 함수가 리턴하는 객체에 해당 프로퍼티가 존재한다면, 404 에러페이지로 이동하게 한다.