[Next.js] Next.js 시작하기: 2편

donguraemi·2023년 8월 23일
0

넥스트JS

목록 보기
2/5
post-thumbnail

리액트는 어플리케이션을 구축하고 구조화하는 방법에 대해 무관심하다. Next.js는 어플리케이션을 구조화하는 프레임워크로, 개발 프로세스와 최종 어플리케이션을 더 빠르게 만들도록 최적화를 제공한다.

How this applies to Next.js

Next.js는 어플리케이션의 development와 production 단계에 대한 기능을 모두 제공한다.

  • Development : 개발자 경험을 개선하기 위해 TypeScript, ESLint 통합, 빠른 새로고침 등을 제공한다.
  • Production : 사용자와 어플리케이션 사용 경험을 최적화 한다. 성능과 접근성을 높이기 위해 코드 변환을 지원한다.

각 환경이 서로 다른 고려사항과 목표를 갖고 있기 때문에 어플리케이션을 development 단계에서 production으로 이동하려면 수행해야 할 작업이 많다. (ex. compile, bundle, minify, code split)


What is Compiling?

compiling
개발자들은 JSX, TypeScript 등 개발자 친화적인 언어를 이용하여 코드를 작성한다. 이러한 언어들은 개발자의 효율성을 향상 시키지만, 브라우저가 이해할 수 있는 자바스크립트로 컴파일 되어야 한다. Next.js에서 컴파일은 코드를 편집하는 개발 단계에 속하며 빌드 단계의 일부로 실행된다.

컴파일은 한 언어로 된 코드를 다른 언어나 해당 언어의 다른 버전으로 출력하는 프로세스를 말한다.


What is Minifying?

minifying
개발자는 사람이 쉽게 읽을 수 있도록 최적화된 코드를 작성한다. 코드는 주석, 공백, 들여쓰기, 여러 줄 등 코드를 실행시키는 데 불필요한 정보들을 포함한다. 축소는 코드의 기능을 유지하면서 주석과 불필요한 코드 형식을 제거하는 과정이다. 즉, 파일 크기를 줄여 어플리케이션의 성능을 향상시킨다.


What is Bundling?

개발자는 더 큰 규모의 어플리케이션을 구축하는 데 사용할 수 있는 모듈, 컴포넌트, 함수로 어플리케이션을 쪼갠다. 이러한 내부/외부 모듈과 외부 패키지를 가져오고 내보내어 파일 종속성을 가진 복잡한 웹을 생성한다. 번들링은 사용자가 웹 페이지를 방문할 때 요청하는 횟수를 줄이기 위해 파일이나 모듈을 최적화된 번들로 병합하는 것이다.


What is Code Splitting?

code splittting
일반적으로 개발자는 어플리케이션을 다양한 URL에서 접근할 수 있는 여러 페이지들로 나눈다. 각 페이지들은 어플리케이션의 진입점이 된다. 코드 분할은 어플리케이션 번들을 각 진입점에 필요한 더 작은 덩어리로 분할하는 과정이다. 해당 페이지를 실행시키는 데 필요한 코드만 로딩하여 어플리케이션의 초기 로딩 시간을 개선한다. Next.js는 코드 분할 기능이 내장 되어 있다. pages/ 디렉토리 내의 각 파일은 빌드 단계에서 자동으로 자바스크립트 번들로 코드 분할된다.

  • 페이지 간에 공유되는 코드는 같은 코드를 다시 다운로드 하는 것을 방지하기 위해 또 다른 번들로 분리된다.
  • 초기 페이지를 불러온 후에, 다른 페이지의 코드를 미리 로드할 수 있다.
  • 동적 불러오기는 최초 로드되는 코드를 수동으로 분할하는 또 다른 방법이다.

Build Time and Runtime

  • Build Time

빌드 시간은 production을 위한 어플리케이션 코드를 준비하는 일련의 단계를 의미한다. 어플리케이션을 빌드하면 Next.js는 어플리케이션 코드를 production에 최적화된 코드로 변환한다.

  • Runtime

런타임은 어플리케이션이 빌드되고 배포된 후에, 사용자의 요청에 대한 응답으로 어플리케이션이 실행되는 기간을 의미한다.


What is Rendering?

리액트에서 작성한 코드를 UI의 HTML 표현으로 변환하려면 피할 수 없는 작업이 있다. 이 프로세스를 렌더링이라고 한다. 렌더링은 서버나 클라이언트에서 발생하고, 빌드 시 미리 혹은 런타임 시 모든 요청에서 발생한다. Next.js를 사용하면 CSR, SSR, SSG의 세가지 유형의 렌더링 방법을 사용할 수 있다.

Next.js의 장점은 페이지 단위로 가장 적합한 렌더링 방법을 선택할 수 있다는 것이다.


Pre-Rendering

pre-rendering
pre-rendering
Next.js는 기본적으로 모든 페이지를 사전에 렌더링 한다. 사전 렌더링은 HTML이 사전에 서버에서 생성된다. 생성된 HTML은 페이지에 필요한 최소한의 자바스크립트 코드만 가지고 있다. 페이지가 브라우저에 의해 로드되면 자바스크립트 코드가 실행되고 페이지가 상호작용할 수 있게 된다. 이 과정을 hydration이라고 한다.

만약 사용하고 있는 어플리케이션이 순수 리액트 어플리케이션이라면, 사전 렌더링이 일어나지 않는다.

CSR (not Pre-rendering)
표준 리액트 어플리케이션에서 브라우저는 서버로부터 빈 HTML을 받는다. 초기 렌더링 작업이 사용자의 장치에서 수행되기 때문에 렌더링되기 전까지 빈 화면을 보게 된다.
csr


SSR vs. SSG

Next.js는 두 가지 사전 렌더링 형태를 가지고 있다. 페이지를 위한 HTML이 생성될 때 일어나는 차이점을 살펴보자.

  • SSR (Server-Side Rendering)

ssr
SSR은 매 요청마다 HTML을 생성하는 사전 렌더링 방식이다. CSR의 경우, JSON 데이터와 자바스크립트를 사용하여 상호작용하는 컴포넌트를 만든다. 반면, SSR의 HTML은 렌더링 속도가 빠르지만 상호작용하지 않는 HTML 페이지를 표시한다.

  • SSG (Static Site Generation)

ssg
SSG는 빌드 시에 HTML을 생성하는 사전 렌더링 방식이다. 콘텐츠는 빌드 시에 한 번 생성되고 CDN에 저장되어 매 요청마다 재사용된다.

npm run dev처럼 개발 모드에서는 모든 요청에 대해 페이지가 사전 렌더링 된다. 이는 개발을 좀 더 쉽게 하기 위함이다.

💥 언제 SSR을, 언제 SSG를 사용하면 좋을까?
SSG는 빌드 시에 한 번 생성하여 재사용하기 때문에 서버가 모든 요청에 대해 페이지를 렌더링하는 것보다 훨씬 빠르다. 따라서 가능하면 SSG를 사용하는 것이 좋다.

하지만 사용자 요청에 앞서 페이지를 미리 렌더링할 수 없다면 SSG는 좋은 방법이 아니다. 예를 들어 자주 갱신되는 데이터를 표시하거나 매 요청 페이지 내용이 변경되는 경우가 있다. 이 경우에는 SSR을 사용하는 것이 좋다.


What is the Network?

Next.js의 경우, 어플리케이션 코드를 원본 서버, CDN, Edge에 배포할 수 있다.

  • Origin Server : 어플리케이션 코드의 원본을 저장하고 실행하는 컴퓨터
  • CDN (Content Delivery Network)
    클라이언트와 기본 서버 사이의 여러 위치에 HTML과 이미지 같은 정적 내용을 저장한다. 새로운 요청이 들어오면 가장 가까운 CDN에서 캐시된 결과를 전송한다. 각 요청마다 계산이 발생할 필요가 없기 때문에 origin 로드가 줄어들며 지리적으로 더 가까운 위치에서 응답이 오기 때문에 속도가 빠르다. Next.js에서는 사전 렌더링이 미리 수행될 수 있으므로 CDN은 작업의 정적 결과를 저장하는 데 매우 적합하여 콘텐츠 전달을 더 빠르게 만든다.
    cdn
  • Edge
    Edge는 사용자와 가장 가까운 네트워크의 주변부를 의미한다. CDN과 유사하게 전 세계의 여러 위치에 배포된다. 그러나 정적 콘텐츠를 저장하는 CDN과 달리 일부 Edge는 작은 코드 조각을 실행할 수 있다.

    전통적으로 클라이언트나 서버에서 수행되었던 작업을 Edge로 이동시킴으로써 클라이언트로 전송되는 코드의 양이 줄고 사용자의 요청의 일부를 Edge가 처리하기 때문에 어플리케이션 성능의 향상으로 이어진다. Next.js는 미들웨어를 사용하여 Edge에서 코드를 실행시킬 수 있다.


Static Generation with and without Data

정적 생성은 데이터 유무에 관계없이 수행될 수 있다. 여기서는 외부 데이터를 가져와야 하는 경우만 살펴보겠다.

static generation with data
일부 페이지의 경우, 외부의 데이터를 먼저 가져오지 않으면 HTML을 렌더링하지 못한다. 예를 들면 파일 시스템에 접근하거나, 외부 api를 가져오거나, 데이터베이스에 질의해야 하는 경우가 있다.

Next.js에서는 getStaticProps를 이용하여 데이터와 함께 정적 생성이 가능하다. 페이지 컴포넌트를 내보낼 때 getStaticProps라는 비동기 함수도 함께 내보낼 수 있다.

export default function Home(props) { ... }

export async function getStaticProps() {
	const data = ...
    return {
      props: data
    }
}

getStaticProps는 페이지에서만 내보낼 수 있다. 페이지가 아닌 파일에서 내보낼 수 없다.


Fetching Data at Request Time

빌드 시점이 아니라 요청 시 데이터를 가져와야 하는 경우에는 SSR을 사용한다. SSR을 사용하기 위해서는 getServerSideProps를 내보내야 한다.

export async function getServerSideProps(param) {
	return {
      props: ...
    }
}

참고자료
NEXT.js : About Next.js
NEXT.js : Pre-rendering and Data Fetching

0개의 댓글