next.js 들어가기 전
-
react, vue, angular 와 같은 SPA 기반 프레임 워크는 CSR로 동작한다.
-
하지만 CSR은 웹크롤링이 되지 않아 SEO 최적화가 어렵다는 단점을 가지고 있다.
-
이 점을 극복하기 위해 react 생태계에선 next란 SSR 프레임 워크를 사용한다.
Next.js :
React에서 SSR을 쉽게 구현하도록 도와주는 프레임워크
Pre-rendering (NEXT.js default)
- next(Pre-rendering) 적용 전
- next(Pre-rendering) 적용 후
NEXT는 브라우저에 렌더링 시 기본적으로 pre-rendering한다.
pre-rendering는 각 페이지들을 미리 HTML문서로 생성하여 저장하고 있는 것이다.
생성된 HTML엔 반드시 필요한 최소한의 JS Code가 들어 있고 이는 페이지가 브라우저에 의해 로드 될 때 실행된다.
이 과정은 hydration이라 불린다.
pre-rendering 시 HTML에 이벤트 핸들러가 적용되어 있지 않는 상태로 HTML DOM 요소 위에 한번 더 JS를 통해 렌더링한다. (Hydration)
pre-rendering 엔 2가지 방법이 있다.
1. SSG(Static Site Generation)
- 빌드 타임에 페이지별로 HTML 생성. 해당 페이지 요청이 올 경우 이미 생성된 HTML 문서 반환.
- 정적 사이트 생성 (페이지를 미리 만들어 놓는다)
- 많은 변화가 필요없는 페이지를 미리 만들어 놓을 때 사용
- HTML 파일이 빌드시에 생성되고 요청시 마다 재사용된다.
- 유저가 요청할 때 이미 생성된 HTML 파일을 반환.
2. SSR(Server Side Rendering)
- 페이지 요청이 올 때마다 서버에서 HTML을 생성 후 넘겨준다.
next에선 성능 상의 이유로 SSG의 방식을 추천한다. → 퍼포먼스에 집중 (CDN*을 통해 더 빠른 응답 가능)
배포 후 빌드 시 콘텐츠가 생성되고 HTML이 CDN*에 저장되어 각 요청마다 재사용된다.
*CDN(Content Delivery Network)
- 지리적 제약 없이 전 세계 사용자에게 빠르고 안전하게 콘텐츠를 전송할 수 있는 콘텐츠 전송기술.
- 정적 콘텐츠(HTML, img)를 저장하고 클라이언트와 Origin서버 사이에 배치.
- 서버와 사용자 사이 물리적인 거리를 줄여 콘텐츠 로딩에 소요되는 시간을 최소화.
- 유저가 새 요청을 보내면 유저와 가까운 CDN에 캐시된 결과 응답.
SSG는 유저의 request에 앞서 pre-render 하여 요청시에 빠르게 페이지를 보여줄 수 있지만
유저와의 interaction이 빈번하게 이뤄지는 페이지의 경우엔 CSR과 함께 SSG를 사용하는 편이 좋다.
CSR과 함께 사용하게 되면 페이지의 일부분(업데이트가 이뤄지는 부분)은 pre-rendering 없이 CSR을 할 수 있게 된다.
-
SSG와 SSR의 차이점
SSG는 빌드 타임에 모든 페이지를 pre-rendering 하고, SSR은 요청시 해당 페이지를 pre-rendering 후 반환 하는 차이이다.
Pages-Data Fetching
페이지별로 data를 fetching할 때, 정적데이터인지 페이지 요청마다 렌더되는 데이터인지에 따라 3가지로 나눠진다.
1. getStaticProps : single data pre-render
-
getStaticProps는 빌드시 고정되는 값으로 빌드 이후에는 수정이 불가능하다.
-
data를 빌드 시 미리 가져오기 때문에 빠른 속도로 페이지가 렌더된다. 빈번한 유저 요청이 없는 페이지를 렌더할 때 유리하다.
2. getStaticPaths : dynamic routing pre-render
- 동적 라우팅 + getStaticProps 시 사용한다. 빌드시에만 작동한다.
- getStaticPaths를 사용하여 빌드 시 정적 렌더링 경로를 설정하고 설정하지 않은 경로로는 접근시에 화면이 보이지 않는다.
3. getServerSideProps : ssr
-
getServerSideProps가 사용된 page는 request time에 server side로 렌더링 된다.
-
빌드와 상관없이, 매 페이지 요청마다 데이터를 서버로부터 가져온다.
-
페이지를 렌더링하기전에 반드시 fetch해야할 데이터가 있을 때 사용
-
서버사이드에서만 실행된다.
-
매 요청시마다 실행된다.
Basic Features
-
Code Splitting
자바스크립트의 모든 코드를 번들링하여 하나로 만드는 것은 규모가 클수록 (파싱 해야하는 정보가 많아질 수록)초기 구동 속도가 느려진다는 단점을 가진다.
next에선 첫 페이지 로딩시 큰 javascript payload를 보내는 것이 아닌 번들을 여러 조각으로 나누어 필요한 부분만 전송하여 로드 타임을 단축시킬 수 있다.
이는 dynamic import 를 사용하여 모듈이 호출 될 때만 모듈을 import한다.
-
next에서 페이지는 Pages란 이름의 폴더 내 파일 명이 .js, .jsx, .ts, .tsx로 export된 리액트 컴포넌트이다.
-
Pages
pages ├── introduce.js ├── login.jsx ├── main.ts └── about.tsx
-
Pages with Dynamic Routes
pages └── posts └── [id].js // -> posts/1, post/2, post/3
Routing
- Index routes
pages/index.js -> '/'
pages/blog/index.js -> '/blog'
- Nested routes
pages/blog/first-post.js → '/blog/first-post'
pages/dashboard/settings/username.js → '/dashboard/settings/username'
- Dynamic route
pages/blog/[id].js → '/blog/:id' ex : '/blog/hello-world'
pages/[username]/settings.js → '/:username/settings' ex : '/marc/settings'
pages/post/[...all].js → '/post/*' ex : '/post/2020/id/title'
Reference
공식 문서
Next.js by Vercel - The React Framework