본문 바로가기
Next.js

Pages

by NANDEV 2022. 12. 23.

Next.js는 pages 폴더 안에 있는 파일 이름을 기반으로 라우팅한다. pages 폴더 안에는 .js, .jsx, .ts, .tsx 파일이 들어갈 수 있으며, 각 파일에는 React Component가 들어간다. 만약 about.js라는 파일을 만들었다면 www.domain.com/about으로 접근할 수 있다.

 

동적 라우팅(Dynamic Routes)

Next.js는 동적 라우팅을 지원하는데 pages/posts/[id].js처럼 대괄호를 추가해서 파일명을 작성하면 동적라우팅이 가능하다. www.domain.com/posts/1로 접근할 수 있다.

 

사전 렌더링(Pre-rendering)

Next.js는 기본적으로 모든 페이지를 사전 렌더링한다. 사전 렌더링이란, 클라이언트(브라우저)측에서 자바스크립트 파일을 통해 렌더링하는 것이 아니라 서버에서 미리 HTML을 만들어 클라이언트에 보내주는 것을 말한다. 이를 통해 더 나은 성능과 SEO가 가능해진다.

 

생성된 각 HTML은 해당 페이지에 필요한 최소한의 자바스크립트 코드와 연결되며, 페이지가 로드되면 자바스크립트 코드가 실행된 후 상호 작용이 가능해진다. 이 과정을 hydration이라고 한다.

 

두 가지 형태의 사전 렌더링

Next.js에는 Static Generation(SSG, 정적 생성)과 Server-side Rendering(SSR, 서버 사이드 렌더링)이라는 두 가지 사전 렌더링 방식이 있으며, 두 방식의 차이점은 HTML을 생성하는 시점이다.

 

  • Static Generation(권장): HTML이 어플리케이션 빌드시 생성되며, 페이지 요청시 이미 만들어진 HTML을 클라이언트에 보내준다.
  • Server-side Rendering: 요청시에 HTML을 생성해서 클라이언트에 보내준다. 페이지를 CDN에서 캐시할 수 없다.

각 페이지별로 사용할 사전 렌더링 방식을 선택할 수 있으며, 여러 방식을 혼합하여 하이브리드 어플리케이션을 만들 수 있다. 성능상의 이유로 SSR보다 SSG를 사용하는 것이 좋다. SSR은 요청시마다 HTML을 생성하기 때문에 서버 측의 부담과 비용이 많이 들지만 SSG는 CDN에 의해 캐시될 수 있어 SSR보다 성능이 좋다. 기본적으로 SSG 사용을 권장하며, SSG와 SSR 뿐만 아니라 Client-side Rendering(CSR, 클라이언트 사이트 렌더링)도 가능하다.

 

Static Generation

SSG를 사용하는 경우 빌드시 HTML이 생성되어 재사용된다. 외부에서 데이터를 가져오는 경우와 가져오지 않는 경우 모두 SSG를 사용할 수 있으며, CDN에서 캐시할 수 있다.

 

Static Generation without data

Next.js는 기본적으로 외부에서 데이터를 가져오지 않는 경우 SSG를 사용해 페이지를 사전 렌더링하며, 이러한 경우 빌드할 때 페이지당 하나의 HTML 파일을 생성한다.

 

Static Generation with data

외부에서 데이터를 가져와야하는 경우 두 가지 시나리오가 있다.

 

  • 페이지의 콘텐츠가 외부 데이터에 의존하는 경우: getStaticProps 사용
  • 페이지의 경로가 외부 데이터에 의존하는 경우: getStaticPaths 사용(보통은 getStaticProps와 같이 사용한다)

 

페이지의 콘텐츠가 외부 데이터에 의존하는 경우

예를 들어 blog.js 파일에서 블로그 게시물 목록을 가져와야할 경우 getStaticProps라는 비동기 함수를 사용할 수 있다. 이 함수는 빌드 시 호출되며, 사전 렌더링에서 가져온 데이터를 페이지 안에 있는 컴포넌트의 props로 전달할 수 있다.

export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

export async function getStaticProps() {
  // API 호출을 통해 데이터를 가져온다.
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // 가져온 데이터를 아래와 같이 return 하면 페이지의 컴포넌트에서 받아서 사용할 수 있다.
  return {
    props: {
      posts,
    },
  }
}

 

페이지의 경로가 외부 데이터에 의존하는 경우

예를 들어 블로그 게시물에 따라 라우팅을 달리해서 게시물을 표시해야하는 경우 getStaticPaths를 사용할 수 있다. 이러한 경우 동적 라우팅 파일(ex. /posts/[id].js) 파일 안에서 해당 함수를 사용한다. 이 함수는 빌드 시 호출되며, 사전 렌더링할 경로를 지정할 수 있다.

export default function Post({ post }) {
  // Render post...
}

export async function getStaticPaths() {
  // API 호출을 통해 데이터를 가져온다.
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // { fallback: false }은 해당하는 경로가 아니면 404임을 의미한다.
  return { paths, fallback: false }
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  return { props: { post } }
}

 

 

SSG를 언제 사용해야 할까?

페이지를 한번 만들고 계속해서 재사용이 가능하기 때문에 가능하면 SSG를 사용하는 것이 좋다. SSG를 사용하면 SSR보다 훨씬 빠르다. 하지만 사용자 요청이 있을 때 페이지를 만들어야한다던지, 데이터가 자주 업데이트 되야할 때 SSG를 사용하는 것은 좋지 않다. 이러한 경우 CSR과 함께 SSG를 사용하거나 SSR을 사용해야한다. SSR을 사용하면 CDN에서 캐시할 수 없어 속도가 느려지지만 페이지는 항상 최신 상태를 유지한다.

 

Server-side Rendering

SSR을 사용하면 요청시에 HTML을 만든다. 페이지에서 SSR을 사용하려면 getServerSideProps라는 비동기 함수를 사용해야한다. 이 함수는 요청시 서버에 의해 호출된다.

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

export async function getServerSideProps() {
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  return { props: { data } }
}

 

반응형

'Next.js' 카테고리의 다른 글

Data Fetching - getStaticProps  (0) 2022.12.29
Data Fetching - getStaticPaths  (0) 2022.12.27
Data Fetching - getServerSideProps  (0) 2022.12.26
Next.js 시작하기  (0) 2022.12.23

댓글