요즘 읽고 있는 책을 보다 Next.js를 사용하는 이유이기도하며 가장 중요한 개념들을 정리해두려고 한다. 현업에서도 얼마 전 에디터와 어드민 페이지를 제외한 모든 페이지를 Next.js 기반의 프로젝트로 마이그레이션을 완료했다. 이제 프로젝트의 꽤 많은 부분을 Next.js와 함께하면서 이미 익숙해진 개념이지만 이번 기회에 확실하게 정리해두고자 한다.
Next.js 는 페이지 별로 렌더링 방법을 전환할 수 있다. 사용할 수 있는 방법은 총 4가지다.
모든 페이지에서 만약 사전 렌더링이 가능하다면 사전 렌더링을 수행한다.
SSG에서는 빌드 시 API 등으로부터 데이터를 얻어, 페이지를 그려 정적 파일로 생성한다.
빌드 시에 getStaticProps 함수가 호출, 함수 내 API 호출 등을 수행하고, 페이지를 그리는데 필요한 props를 반환한다. 화면을 그린 후 해당 결과는 정적 파일의 형태로 빌드 결과로 저장한다. 페이지 접근이 발생하면 미리 생성한 정적 파일을 클라이언트에 보낸다. 초기페이지를 그린 이후 클라이언트는 일반 리액트처럼 동적으로 화면을 그릴 수 있다.
SSG는 유저가 접근 시 가지고 있던 정적파일을 전달하기만 하기때문에 초기 화면을 그리기까지가 빠르다. 하지만, 가지고 있던 데이터가 마지막 빌드 시점의 데이터이기 때문에 stale상태이므로 오래된 데이터가 보여질 가능성이 크기 때문에 실시간성이 중요한 웹서비스는 맞지 않는 방법이다. 블로그 등의 서비스가 적절해보인다! 또한, 성능이 뛰어나기 때문에 Next.js에서도 SSR보다는 SSG를 권장한다.
이는 기본적인 리액트로 프로젝트를 만들었을 때 사용하게되는 일반적인 방법으로 서버로부터 빈 HTML파일을 받아와 해당 DOM에 리액트 컴포넌트에 비동기로 가져온 데이터를 추가한 뒤 그려 저장한다. 그렇기에 유저는 데이터가 오기까지 초기 로딩 혹은 빈페이지를 보게될 가능성이 커서 초기화면을 그리는 것이 중요하지 않고, 실시간성이 중요한 페이지에 적합하다.
유저가 접근했을 때마다 getServerSideProps를 호출하고, 그 결과 props를 기반으로 한 페이지를 서버측에서 그린 후 클라이언트에 전달한다.
SSG와 다르게 매 접근 시마다 서버에서 데이터를 가져와 화면을 그리기 때문에 오래된 데이터를 보여주거나 SEO에 대한 유효성을 기대할 수 있지만, 그 만큼 프론트서버에서의 처리가 많아지기 때문에 다른 방법에 비해 지연이나 부하가 생길 수 있다. 최신 가격이 표시되는 제품 페이지 등, 항상 최신 데이터를 보여주고자 하는 서비스에 적합하다.
사실 이 개념이 제일 와닿지않고 익숙하지 않아 공부해보고자 마음먹었다. ISR은 SSG의 응용이라할 수 있는 렌더링 방식이다. 사전에 생성해둔 페이지를 전달하면서, 동시에 접근이 발생함에 따라 페이지를 다시 생성해서 새로운 페이지를 전송할 수 있다. 페이지에 접근이 발생했을 때 SSG처럼 기존에 생성해둔 정적파일을 보내주지만 이 때의 데이터에 유효 기간을 설정할 수 있고 만약 유효기간이 지난 시점에서의 접근이 발생한다면 백그라운드에서 다시 getStaticProps를 호출하여 화면을 그리고 서버에 저장된 페이지의 데이터를 갱신한다.
SSR과 달리 요청 시에 서버에서 처리를 하지 않기 때문에 SSG와 마찬가지로 초기 지연을 짧게할 수 있고 어느정도 최신 데이터를 기반으로 하는 페이지를 초기에 그리는 것이 가능하다. SSR과 SSG의 중간과 같은 렌더링 방법이라고 할 수 있다.
Next.js에서는 페이지에서 구현하는 함수나 해당 함수의 반환값에 따라, pages의 렌더링 방법이 달라진다.
종류 | 데이터 취득에 사용하는 주요 함수 | 데이터 취득 시점 | 보충 설명 |
---|---|---|---|
SSG | getStaticProps | 빌드 시(SSG) | 데이터 취득을 전혀 수행하지 않는 경우도 SSG에 해당 |
SSR | getServerSideProps | 사용자 요청 시(서버 사이드) | getInitialProps를 사용해도 SSR |
ISR | revalidate를 반환하는 getStaticProps | 빌드 시(ISR) | ISR은 배포 후에도 백그라운드 빌드가 실행된다. |
CSR | 그 밖의 임의의 함수(useSWR 등) | 사용자 요청 시(브라우저) | CSR은 SSG/SSR/ISR과 동시에 사용 가능 |
undefined pages는 그 종류에 따라 데이터 취득에 사용할 수 있는 함수가 다르고, 페이지 컴포넌트에서 모든 표시 부분을 구현할 필요는 없다. 페이지 사이에서 공통으로 사용하는 코드나 UI부분은 pages 디렉터리 밖에서 정의하고 임포트해서 사용이 가능하다.