Next js 는 Node 에서 실행되기 때문에 웹브라우저에서 제공하는 전역객체 (window, document 등) 에 접근할 수 없다.
▶ 코드분할
코드분할이란 서로 다른 URL 에서 접근할 수 있는 여러 페이지로 분할하는 것이다.
이렇게 분할된 각 페이지는 응용프로그램에 대한 고유한 진입점이 된다.
Next.js 에는 코드분할을 지원하는 기능이 내장되어있다.
pages/ 디렉토리 내의 각 파일은 빌드 단계에서 자동으로 자체 자바스크립트 번들로 코드분할된다.
ㄴ .. 이게 무슨말일ㄲ ㅏ?
▷ pages 디렉토리
pages 디렉토리는 Next.js 에서 핵심적인 역할을 하는 디렉토리 중 하나로, 각 페이지에 대한 엔드포인트를 정의하는 역할을 한다. 즉 'pages' 디렉토리에 파일을 생성하면, 해당파일 이름에 맞는 경로로 라우팅이 가능해진다.
이런 페이지 파일들은 Reat 컴포넌트로 작성된다. 그래서 각 파일은 화면에 보여지는 페이지의 일부를 구성하는 코드를 포함하고 있다.
그리고 Next.js 는 이러한 페이지 파일들을 빌드 시점에 자동으로 서버사이드 렌더링을 위한 코드로 변환하여 클라이언트 요청이 있을 때마다 해당 페이지를 렌더링 할 수 있도록 한다.
Next.js 에서 애플리케이션을 빌드할 때 무슨일이 일어나는가 ?
Next.js 에서 애플리케이션을 빌드할 때, Next.js 는 코드를 빌드하여 배포 가능한 파일로 변환한다. 이때 Next.js 는 서버 측 코드와 클라이언트 측 코드를 모두 빌드한다. 그리고 빌드된 코드는 서버에 배포된다.
빌드된 코드는 사용자가 사용할 준비가 된 프로덕션 최적화 파일이다. 이 파일은 코드가 최적화 되어있으며, 서버사이트 렌더링과 같은 기능이 가능한 상태로 빌드되며, 이 파일은 Next.js 서버에서 실행된다. 이렇게 빌드된 파일을 실행하면 Next.js 서버는 사용자의 요청에 따라 적절한 페이지를 렌더링하여 반환한다.
렌더링이란 ?
React 작성한 코드를 해당 UI 에 대한 HTML 로 변환하기 위한 작업 단위가 있으며 이 프로세스를 렌더링이라고 한다.
렌더링은 서버 또는 클라이언트에서 발생할 수 있다.
애플리케이션을 빌드할 때, Next.js 는 코드를 서버에 배포하고 사용자가 사용할 준비가 된 프로덕션 최적화 파일로 변환한다.
이 파일에는 다음과 같은 사항이 포함되어있다
- 정적으로 생성된 페이지용 HTML 파일
- 서버에서 페이지를 렌더링하기 위한 자바스크립트 코드
- 클라이언트에서 페이지를 동적으로 만들기 위한 자바스크립트 코드
- CSS 파일
▶ Next.js 의 렌더링 유형
1. Pre-Rendering
2. 클라이언트 사이드 렌더링
3. 정적 사이트 생성
▷ ClientSide-Rendering
일반적인 React 애플리케이션에서 브라우저는 서버로부터 빈 HTML + UI를 구성하기 위한 JS 를 전달받는다.
초기 렌더링 작업이 사용자 장치에서 발생하므로 이를 ClientSide-Rendering 이라고 한다.
- React 의 useEffect() 또는 useSWR 과 같은 데이터 페칭 훅을 사용해서 데이터를 가져오도록 선택해서 Next.js 애플리케이션의 특정 컴포넌트에 대해 ClientSide-Rendering 을 사용하도록 선택할 수 있다.
▷ Pre-Rendering
반면 Next.js 는 모든 페이지를 Pre-Rendering 한다. Pre-Rendering 은 서버에서 DOM 요소들을 Build 하여 HTML 을 생성하는 것을 말한다.
ClientSide-Rendering 의 경우 렌더링 작업이 수행되는 동안 사용자에게 빈 페이지가 표시된다.
Pre-Rendering 의 경우 사용자는 완성된 HTML 을 볼 수 있다.
▶ Pre-Rendering 의 두가지 유형
Pre-Rendering 을 동적으로 해서 페이지를 생성하느냐, 정적으로 페이지를 생성하느냐 !
▷ 1. 서버사이드 렌더링 (SSR)
요청이 올 때마다 서버에서 HTML 을 생성하고,
페이지를 동적으로 만들기 위한 자바스크립트 명령이 클라이언트로 전송된다.
따라서 항상 최신 상태를 유지해야하는 웹페이지나, 분석차트 등 사용자의 요청마다 동적으로 페이지를 생성해 다른 내용을 보여주어야 하는 경우에 사용된다.
클라이언트에서 HTML 은 빠르고 정적인 페이지를 표시하는데 사용되는 반면,
리액트는 JSON 데이터와 자바스크립트를 사용하여 컴포넌트를 동적으로 만든다.
이 과정을 하이드레이션(hydration)이라고 한다.
Next.js 에서는 getServerSideProps() 를 사용해 서버사이트 렌더링 페이지를 선택할 수 있다
getServerSideProps() 함수 안에 파라미터는 여러 정보를 받아올 수 있다.
▷ 2. 정적 사이트 생성 (Static Site Generation)
SSG 는 빌드를 진행할 때 pages 폴더에서 작성한 각 페이지들에 대해 각각의 문서를 생성해서 static 한 파일로 생성한다.
해당 페이지에 대한 요청이 발생하게 되면, 이 페이지들을 재생성하는 것이 아닌 이미 생성된 페이지를 반환한다.
따라서 생성이 완료되 HTML 문서를 재활용 하기 때문에 응답 속도가 매우 빠르다.
SSG 를 사용하면 HTML 이 서버에서 생성되지만, SSR 과 달리 런타임에 서버가 없다.
콘텐츠는 애플리케이션이 배포될 때 빌드 때 (npm run build) 한번만 생성되며 HTML 은 CDN 에 저장되어 각 요청에 대해 재사용된다.
.. ??
⬇️
SSG에서는 HTML 파일이 서버에서 미리 생성되므로 런타임에는 서버가 필요하지 않다.
반면 SSR 은 서버측에서 동적으로 HTML 을 생성하는 방식이기 때문에 클라이언트 요청에 따라 서버에서 데이터를 가져와 HTML 을 생성하고 클라이언트에게 전달한다. 따라서 SSR 에서는 런타임에 서버가 필요하다.
=> SSG 에서는 런타임에 서버가 없이 미리 생성된 HTML 파일을 사용해 클라이언트에게 전달되는 반면, SSR 에서는 런타임에 서버가 필요하고, 클라이언트 요청에 따라 HTML 이 동적으로 생성된다.
Next.js에서 getStaticProps() 를 사용해 컴포넌트를 렌더링하기 전에 서버에서 데이터를 가져와서 props 로 전달할 수 있다.
getStaticProps()
- 서버측에서만 실행되는 함수이다.
- 클라이언트 측에서 실행되지 않는다.
- 빌드 시 딱 한번만 호출된다. => 다른 요청이 들어올 때마다 서버에서 데이터를 가져오는 것보다 훨씬 빠르다.
- API 와 같은 외부데이터를 받아 Static Generation 하기 위한 용도이다.
블로그를 예로 들어보자.
서버에서 가져온 블로그 포스트 데이터를 사용해 '/posts' 페이지를 만들어보겠다.
먼저 getStaticProps() 를 사용해 서버에서 포스트 데이터를 가져온다.
// pages/posts.js
import React from 'react';
export default function Posts({ posts }) {
return (
<div>
{posts.map(post => (
<div key={post.id}>
<h2>{post.title}</h2>
<p>{post.body}</p>
</div>
))}
</div>
);
}
export async function getStaticProps() {
// 서버에서 포스트 데이터 가져오기
const res = await fetch('https://jsonplaceholder.typicode.com/posts');
const posts = await res.json();
// 가져온 데이터를 props 객체에 추가하여 반환
return {
props: {
posts,
},
};
}
위의 예제에서는 fetch() 함수를 사용해 포스트 데이터를 가져오고, 가져온 데이터를 props 객체에 추가해 반환한다.
그리고 Posts 컴포넌트에서는 props 를 받아와 포스트 데이터를 출력한다.
이렇게 했을 경우 '/posts' 페이지에 접속하면 서버에서 포스트 데이터를 가져와서 초기 렌더링 시에 보여준다.
getStaticProps() 함수를 사용하면 서버에서 데이터를 가져와서 초기 로딩 시간을 개선할 수 있다.
getStaticProps() 함수를 사용하지 않았을 경우엔 ?
getStaticProps()를 사용하지 않고 서버사이드 렌더링 방식으로 구현하면, 초기 렌더링 시에 사용자는 빈 화면을 먼저 보게 될 수 있다. 서버사이드 렌더링에서는 클라이언트 측 코드가 실행되기 전에 서버에서 페이지가 렌더링되고, 이후에 클라이언트 측 코드가 실행된다.
그리고 서버에서 페이지를 렌더링 할 때 데이터를 가져와서 페이지에 채운다. 데이터를 가져오는 시간동안 사용자는 빈 화면을 보게 되는것이다.
getStaticProps() 함수를 사용했기 때문에 !
getStaticProps()를 통해 빌드 시에 서버에서 데이터를 불러와 페이지를 생성하고, 생성된 페이지를 캐싱한다. 그래서 사용자가 페이지를 요청할 때 마다 서버에서 데이터를 가져오는 대신 캐싱된 페이지를 빠르게 반환한다.
따라서 초기 렌더링 속도를 높이고, 사용자가 빈화면을 보는 문제를 해결할 수 있다 !
'Next' 카테고리의 다른 글
[Next] 정적생성 / getStaticPath() (0) | 2023.02.20 |
---|---|
[Next] 폴더 구조 및 동작 (0) | 2023.02.20 |