현재는 B2B 기업에서 웹 개발을 하고 있기 때문에 Next.js 를 딱히 도입해야 할 필요가 없어서 쓸 일이 없지만
서비스 프로덕션 환경에서는 Next.js가 필수적이라는 이야기를 많이 듣기도 했고 왜 좋은지 궁금해서 Next.js 공부를 시작했다.
Next.js 를 쓰는 이유, 렌더링 과정 등을 정리하면서 내 머릿속에 다시 한 번 집어 넣기 위해 쓰는 것이기 때문에 예쁘고 보기 좋게 쓰진 못하겠지만!
이런 정리가 누군가에겐 도움이 될 거라 생각합니다 ㅎㅎ
먼저 Next.js 를 정리하기 전에 렌더링 종류에 대해서 정리해보자.
렌더링 종류
1. CSR (Client Side Rendering)
우리가 쓰는 React는 CSR 방식으로 동작한다.
CSR은 말 그대로 클라이언트 측에서 렌더링을 담당하는데, 서버에 요청하여 HTML과 JS를 모두 불러와 렌더링을 시작한다. 추가적으로 CSS 파일이나 폰트, 이미지 등등은 HTML, JS 를 불러온 이후 로드된다고 한다.
이때 CSR에서 다운 받은 HTML파일은 div 태그만 존재하는 빈 껍데기로 렌더링 준비가 되지 않은 html 파일이다.
그래서 HTML 과 JS파일을 다운 받은 후 JS 파일을 실행시키고 나서야 index.js가 root 태그를 화면에 렌더링 할 수 있게 된다.
따라서 사용자는 1. html 파일 로드 2. js 파일 로드 3. js 실행 까지 빈 화면만 보게 되기 때문에 사용자가 초기 로드 시 빨리 화면을 봐야 하는 서비스라면 csr은 적합하지 않다.
장점
- 초기에 모든 html js파일을 불러오기 때문에 페이지 간 이동이나 사용자의 인터렉션이 많은 경우 오히려 csr이 좋을 수 있다.
단점
- 초기 로딩 시간 오래 걸려 사용자의 이탈이 증가할 수 있다.
2. SSR(Server Side Rendering) 와 SSG (Static Site Generation)
SSR과 SSG를 한번에 묶은 이유는 둘 다 pre-rendering 방식으로 동작하기 때문이다.
이 둘의 차이는 ssr은 페이지 이동이 있을 때마다 html을 새로 생성한다는 것이고 ssg는 html 을 재사용할 수 있다는 것? 인데 아직 잘 와닿지 않는다.
SSR은 서버 측에서 렌더링을 담당하는 렌더링 방식으로 서버에서 렌더링을 한다는 것은 HTML에 내용이 있다는 것을 의미한다.
HTML 파일에 내용이 있으므로 화면에 렌더링 할 수 있는 상태라는 것!
SSR에서는 서버에서 HTML 파일을 받을 때 렌더링 될 준비(HTML 에 내용물이 있는 상태)가 된 HTML 파일을 받아 화면에 먼저 보여주게 된다. 이때 화면에 빈 껍데기가 아닌 HTML 파일 먼저 렌더링 한 후 JS 파일을 서버로부터 로드한다.
따라서 화면에서는 정적인 페이지만 있을 뿐 화면을 클릭해도 동작하지 않는다. 이후 JS 파일을 로드 후 화면에 보여준 HTML 파일에 JS파일을 연결하는데, 이 과정을 정적인 페이지에 동적인 요소를 가미한다(수분을 공급한다)고 해서 Hydration이라 한다.
따라서 사용자는 1. 렌더링 준비가 된(내용물 있는) html 파일 로드 후 화면 보기 가능 2. js파일 로드 3. js파일 연결(Hydration) 후 인터랙션 가능
1단계 후 화면을 볼 수 있기 때문에 인터랙션은 되지 않지만 빠르게 화면을 볼 수 있게 된다.
장점
- 초기에 사용자가 빠르게 화면을 볼 수 있어 사용자 이탈이 적어진다.
- 초기에 html 파일에 내용물이 포함되어 있기 때문에 검색 엔진 최적화에 좋다. 웹크롤러는 html 내용을 수집하여 색인하기 때문
단점
- 초기 로드 시 모든 파일을 불러오지 않기 때문에 요청 시마다 서버에 부하가 갈 수 있다. 그 이유는 한번에 불러오지 않고 요청 시 마다 브라우저 → 프론트 서버 → 백엔드 서버 → 데이터베이스를 거쳐 데이터를 가져온 후, 브라우저가 데이터가 그려지는 과정을 반복하기 때문.
- 사용자 인터랙션이 많은 페이지의 경우 페이지 간 이동 시에는 csr의 렌더링 속도가 더 빠르다.
그래서 Next.js 란?
Next.js는 기본적으로 ssg로 동작하고 ssr도 지원하는 React 기반 프레임워크로, 한 마디로 React에서 ssr이 가능하게 하는 프레임워크이다.
위에서 정리한 ssr을 보면 매 요청마다 추가적으로 리소스를 불러오기 때문에 인터랙션이 많은 경우 ssr을 쓰면 오히려 안될 것 같은데..? 라는 생각이 들었다.
그러나 Next.js 는 SSG를 기본으로 사용하고, SSR을 사용할 수 있으며 기본적으로 SSG를 사용하기 때문에 빌드 시점에만 서버 사이드에서 pre-render한 파일들을 보내주고, 그 이후에는 CSR로 페이지를 이동하는 것이라고 한다.
한 마디로 SSR 과 CSR 을 모두 사용한다는 것!
따라서 SSR을 사용하지만 페이지 이동 시마다 HTML과 JS파일을 전체적으로 다시 불러오는 것은 아니며, 필요한 데이터의 업데이트만 수행하게 된다.
이를 통해 빠른 페이지 전환과 효율적인 네트워크 사용이 가능한 것이다.
Next.js의 렌더링 과정
Next.js는 모든 페이지의 html을 pre-render 해놓고 생성된 html은 최소한의 자바스크립트와 연결되게 하여 브라우저가 페이지를 로드하면 그때 유저가 페이지와 상호작용 할 수 있다.
이때, Next.js가 pre-render 하는 방식은 두 가지인데
1) SSG
빌드 타임에 HTML이 생성되어 매 요청마다 이를 재사용. 즉, 빌드 시점 이후에는 서버에게 따로 요청하지 않는다.
2) SSR
매 요청마다 HTML을 생성. 여기서의 '매 요청'은 웹 사이트의 페이지를 접속하거나 페이지를 새로고침할 때 발생하는 요청을 말한다.
SSR 방식에서는 클라이언트의 각 요청마다 서버가 해당 페이지의 데이터와 리소스를 가져와서 HTML을 동적으로 생성
장점
- Pre-rendering과 CSR의 장점을 모두 사용할 수 있게 해준다.
- 자세히 다루진 않았지만 Next.js에서는 파일 시스템 기반의 라우팅 구조로 인해 React 보다 라우팅 처리를 더 쉽게 할 수 있게 되었다. ( App router 관련해서는 또 다시 정리하여 포스팅 해보려고 한다. )
단점
1. 익숙하지 않다..? 초기 학습곡선이 발생할 수 있다.
2. SSR을 사용하기 때문에 서버 부하가 발생할 수 있다.
Next.js 와 렌더링 개념 정리 끝!
덕분에 이해되지 않고 물음표 가득했던 것들이 어느정도 해소되었다.
혹시 추가적으로 더 알게 되는 내용이 있거나 틀린 부분이 있다면 지속적으로 추가 수정 할 예정입니다 :)