Next.js 동작 원리

김혜원·2022년 2월 20일
5
post-thumbnail

해당 블로그로 이전했습니다.

Next.js 12버전을 기준으로 작성한 글입니다.

Next.js는 서버사이드 렌더링(SSR)을 지원하는 React 프레임워크입니다.

기존의 전통적인 SSR 방식은 웹페이지 이동 시에 페이지를 요청할 때마다 서버로부터 새롭게 생성된 HTML 파일을 받아와 화면에 렌더링하였습니다. 이러한 방식은 서버 자원을 많이 소모하고 불필요한 트래픽을 유발했습니다.

Next.js는 초기 페이지 로딩에 대해서는 SSG, SSR 방식으로 동작시킬 수가 있고, 이후의 요청에 대해서는 기본적으로 CSR 방식으로 동작하기 때문에 SSR 방식의 장점인 SEO에 유리하면서도 CSR의 이점을 활용할 수 있습니다.

Next.js의 렌더링 방식

https://nextjs.org/learn/basics/data-fetching/two-forms

Next.js에서는 서버사이드 렌더링(SSR), 정적 사이트 생성(SSG), 클라이언트사이드 렌더링(CSR) 방식을 모두 사용할 수 있습니다. 각 페이지에 사용할 사전 렌더링 방식을 선택할 수 있기 때문에 상황에 맞게 SSG, SSR, CSR을 사용하여 하이브리드 앱을 만들 수 있습니다.

Pre-Render

Next.js는 기본적으로 모든 페이지를 Pre-Render(사전 렌더링)합니다. 파일 사전 렌더링은 빠른 초기 렌더링과 SEO에 유리하고, 유저가 초기 유입 시 빈 페이지를 보지 않아도 된다는 장점이 있습니다.

서버에서 HTML 요소를 모두 구성한 후 클라이언트에 전달해주는데, 이때 클라이언트가 전달받은 HTML은 정적인 뷰에 해당하고 Javascript 번들 파일이 로드되기 전이므로 Pre-Render 상태에서 인터렉티브한 동작이 불가한 상태입니다.

두 가지 방식의 Pre-Render

SSG: HTML이 빌드 시 생성되며 각 요청에서 재사용됩니다.
SSR: HTML이 각 요청에 대해 생성됩니다.

Hydration

Hydration은 서버가 사전 렌더링된 HTML 파일을 전송한 후 번들링된 Javascript 파일을 클라이언트에게 전송하여, 클라이언트에서 HTML 코드와 Javascript 코드를 서로 매칭시키는 과정을 말합니다. Hydration 이후, 어플리케이션은 인터렉티브한 동작을 수행할 수 있게 됩니다.

외부 데이터를 패치하는 경우

일부 페이지의 경우, 외부 데이터를 먼저 가져오지 않고는 HTML을 렌더링할 수 없는 경우가 있습니다. Next.js는 getStaticProps, getServerSideProps 함수를 제공하여 데이터를 사용한 정적 생성, 서버사이드 렌더링 방식을 지원합니다.

getStaticProps

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

export async function getStaticProps() {
  // Get external data from the file system, API, DB, etc.
  const data = ...

  // The value of the `props` key will be
  //  passed to the `Home` component
  return {
    props: ...
  }
}

getStaticProps 함수는 빌드 시 실행되고 외부 데이터를 가져와 페이지 컴포넌트 내부에서 props로 받아올 수 있습니다. SSG는 빌드 시에 한 번 발생 하기 때문에 자주 업데이트되거나 모든 사용자 요청에 따라 변경되는 데이터에는 적합하지 않습니다. 데이터가 변경될 가능성이 있는 경우 서버사이드 렌더링을 사용할 수 있습니다.

getServerSideProps

function Page({ data }) {
  // Render data...
}

// This gets called on every request
export async function getServerSideProps() {
  // Fetch data from external API
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  // Pass data to the page via props
  return { props: { data } }
}

빌드 시가 아닌 페이지 요청 시마다 외부 데이터를 패치해야하는 경우 서버사이드 렌더링을 이용합니다. getServerSideProps가 적용된 페이지는 요청 시마다 새로운 HTML이 생성되기에 캐싱이 적용되는 SSG 방식에 비해 느립니다. 그렇기 때문에 항상 최신 데이터를 가지는 페이지를 사전 렌더링하는 경우에만 사용하도록 합니다.

외부 데이터를 사전에 패치할 필요가 없는 경우

외부 데이터가 필요하지 않은 페이지 부분을 사전 렌더링합니다. 정적 HTML이 로드되면 JavaScript를 사용하여 외부 데이터를 가져오고 받아온 데이터를 채워넣습니다. 이러한 방식은 SEO가 상관없는 비공개 페이지 등에 적합합니다.

Next.js 사용시의 이점

  • 코드 스플리팅을 지원합니다. 기본적으로 pages/ 디렉토리 내의 파일들은 빌드 단계에서 자동으로 각각의 번들 파일로 코드 분할됩니다. 그렇기 때문에 특정 페이지를 실행할 때, 필요한 코드만 로드하여 초기 로드 시간을 개선할 수 있습니다.
  • Next.js는 모든 페이지를 사전 렌더링합니다. 서버에서 각 페이지에 대한 HTML을 미리 생성해서 클라이언트로 전송해주기 때문에 SEO에 유리합니다.
  • API Routes을 활용하여 API 엔드포인트 pages/api 로 빌드할 수 있습니다. 생성된 API 경로에 직접 요청을 보내거나 외부 API를 마스킹하여 안전하게 통신할 수 있습니다.

참고
https://nextjs.org/docs/getting-started
https://nextjs.org/learn/foundations/about-nextjs

profile
좋은 코드를 작성하는 것에 관심이 많은 프론트앤드 개발자입니다. 🏠 블로그 이사 hyeewooon.tistory.com

0개의 댓글