이 글은 Next.js의 공식문서중 How Next.js Works 페이지의 내용을 정리하는 글이다.
Next.js를 처음 접하면서 정리한 간단한 요약정도로 보면 좋을것 같다.
How Next.js Works
Compiling
개발자들은 개발자에게 친화적인 TypeScript, JSX, 모던JS 버전의 코드를 작성합니다.
작성된 코드는 브라우저가 이해할 수 있는 JavaScript로 컴파일 되어야 하죠.
Next.js는 Rust로 작성된 컴파일러와 저수준의 프로그래밍 언어, SWC플랫폼을 통해 컴파일링을 하고 있습니다.
swc-project : https://github.com/swc-project/swc
GitHub - swc-project/swc: Rust-based platform for the Web
Rust-based platform for the Web. Contribute to swc-project/swc development by creating an account on GitHub.
github.com
Minifying
개발자들은 인간 친화적인 코드를 작성을 합니다. 그 코드들은 실행에 필요 없는 부분도 포함하고 있습니다. 예를들면 주석, 공백, 들여쓰기, 줄바꿈 문자들을 말이죠.
Minification은 필요없는 문자들과 주석들을 제거하여 파일의 사이즈를 줄여 최적화 해줍니다. Minification된 코드는 원래의 기능을 동일하게 수행합니다.
Bundling
개발자들은 어플리케이션을 모듈, 함수등의 작은 단위로 나누어서 개발합니다. Export와 Import를 모듈간에 사용하게되면 외부 라이브러리를 사용하는것 만큼의 의존성을 만들게 됩니다,
Bundling은 의존성을 해결하는 과정이고, 파일들을 모아 하나의 최적화된 파일을 만들어 줍니다. 번들링을 하게 되면, 사용자 브라우저의 요청의 수를 줄여주어 최적화도 이뤄낼 수 있습니다.
Code Splitting
개발자들은 보통 URL을 통해서 접근할 수 있는 각각의 여러 페이지들로 어플리케이션을 나누곤 합니다. 각각의 페이지들은 어플리에이션의 유일한 진입점(entry point)이 됩니다.
Code-Splitting은 route별로 어플리케이션을 작은 조각으로 나누는 작업입니다. Code-Splitting을 통해서 필요한 페이지의 코드만 불러오기 때문에, 어플리케이션의 초기 로딩시간을 줄일 수 있습니다.
Next.js는 "pages/" 디렉토리 내의 파일들을 자동으로 code splitting을 해주는 기능을 내부적으로 지원하고 있습니다. 더 나아가서, 페이지간에 코드를 공유하여 동일한 코드를 불러오지 않습니다. 또한 사용자가 사용할 것 같은 페이지를 pre-loading the code를 통해 미리 로딩할 수 있고, Dynamic imports를 통해 직접 어떤 코드를 미리 불러올지 정할 수 있습니다.
Build Time and Runtime
BuildTime에 Next.js는 작성된 코드를 배포에 최적화된 파일로 만들어 서버와 사용자에 배포할 준비를 합니다.
이때 작성되는 파일은 아래와 같습니다.
* 페이지별로 작성된 HTML파일.
* 서버에서 렌더링 될 Javascript코드.
* 사용자와 상호작용하며 만들어질 페이지를 위한 Javascript코드.
* CSS 파일들
Runtime은 사용자의 요청에 응답하며 동작하는 시간을 의미합니다. 어플리케이션이 build되고 배포된 다음입니다.
What is Rendering?
React로 작성된 코드를 HTML코드로 변환하는 과정에서 피할 수 없는 작업이 있습니다. 바로 렌더링 작업입니다. 렌더링 작업은 서버에서 수행할 수도 있고, 클라이언트에서 수행할 수도 있습니다. 또한 렌더링은 빌드전에 일어나거나, 모든 요청에 일어날 수도 있습니다.
Next.js는 세가지의 렌더링 방법을 제공하고 있습니다. Server-Side Rendering, Static Site Generation 그리고 Client-Side Rendring입니다.
Client Side Rendering
일반적인 React Applicatio에서는 브라우저가 빈 HTML파일을 받고, Javascript의 동작으로 UI를 만들게 됩니다. 이것을 Client-Side rendering이라 부르고, 사용자의 기기에서 일어나는 작업입니다.
Pre-Rendering
Server-Side Rendering과 Static Site이 Pre-Rendering 의 범주에 속합니다. 왜냐하면 client로 보내기 전에 sever측에서 외부 데이터를 불러오고, React 컴포넌트를 HTML로 변환하는 과정을 하기 때문입니다.
Pre-Rendering은 사용자의 기기에서 Javascript로 전부 처리하는게 아닌, 서버에서 작업을 앞당겨, HTML을 생성하는 작업을 의미합니다. 기본적으로 매 Page마다 pre-rendering을 수행합니다. Client-Side 어플리케이션이 렌더링 작업을 하며 하얀색 빈 화면을 보여주는동안, pre-rendered 어플리케이션은 완성된 HTML을 보게됩니다.
Server-Side Rendering
Server-Side 렌더링은 매 요청마다 HTML페이지를 생성합니다. 생성된 HTML, JSON, Javscript명령들은 사용자에게로 보내집니다. Client-Side Rendering에서는 React가 JSON데이터와 Javscript명령들이 상호작용 할 수 있는 컴포넌트를 만드는동안 미리보기와 같은 상호작용 할 수 없는 컴포넌트를 보여주곤 했습니다. 이 과정을 hydration이라고 합니다.
Next.js에서는 Server-Side렌더링의 여부를 getServerSideProps.를 통해선택할 수 있습니다.
Static Site Rendering
Static Site 렌더링은 서버에서 HTML을 생성합니다. 하지만 Server-Side렌더링과는 다르게, 작업시간이 소요되지 않습니다. 컨텐츠를 build time에 한번 생성하고, 생성된 HTML은 CDN에 저장되어 요청마다 재사용 됩니다.
Content Delivery Network
CDN은 정적인 콘텐츠를 저장할 수 있는 저장소 입니다. 세계 곳곳에 배치되어있고, 사용자와 원본 서버의 사이에 위치합니다. 새로운 요청이 들어오게 되면, 가장 가까운 CDN에서 사용자에게 cache된 결과들을 응답해 줍니다.
CDN은 지역적으로 가까운곳에 위치하기 때문에, 더 빠르게 사용자에게 응답을 줄 수 있습니다. 또한 원본서버에서 모든 응답을 처리할 필요가 없기 때문에 부하가 줄어들게 됩니다.