My Boundary As Much As I Experienced

Next.js의 pre-rendering이란? 본문

FrontEnd/Next.js

Next.js의 pre-rendering이란?

Bumang 2024. 6. 25. 22:20

Next.js에서 프리 렌더링(Pre-rendering)은 각 페이지를 사전 렌더링하여 HTML을 미리 생성하는 방법이다.

Next.js는 프리 렌더링을 통해 빠른 페이지 로드를 제공하며, SEO(검색 엔진 최적화)에도 도움을 준다.

Next.js에는 두 가지 주요 프리 렌더링 방식이 있다.

정적 사이트 생성(Static SiteGeneration)과 서버 사이드 렌더링(Server-side Rendering)이다.

1. 정적 사이트 생성 (Static Site Generation)

정적 생성은 빌드 시 각 페이지에 대한 HTML을 생성하고, 그 HTML을 재사용하는 방식이다.

이 방식은 성능이 뛰어나며 모든 요청에 대해 동일한 HTML을 제공한다.

정적 사이트 생성은 콘텐츠가 자주 변경되지 않는 페이지에 적합하다.

정적 사이트 생성의 예제

정적 생성은 getStaticProps와 getStaticPaths 함수를 사용하여 데이터를 가져올 수 있다.

// pages/index.js
import { useEffect, useState } from 'react';

// 정적 생성 데이터 가져오기
export async function getStaticProps() {
  // 외부 API에서 데이터를 가져옴
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const posts = await res.json();

  return {
    props: {
      posts,
    },
  };
}

export default function Home({ posts }) {
  return (
    <div>
      <h1>Posts</h1>
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

getStaticPaths

정적 생성 시 동적 경로를 사용하는 경우 getStaticPaths를 사용하여 빌드 시 생성할 경로를 정의할 수 있다.

params 객체

각 경로는 params 객체를 포함해야 한다.

이 객체는 페이지의 파일명에서 정의된 동적 부분을 포함한다.

예를 들어, 페이지 파일이 pages/posts/[id].js인 경우 params 객체는 { id: 'value' } 형식을 가진다.

fallback 옵션

fallback 옵션은 경로가 존재하지 않을 때 어떻게 처리할지를 결정한다.

  • fallback: false: 지정되지 않은 모든 경로는 404 페이지를 표시한다.
  • fallback: true: 지정되지 않은 경로를 처음 요청할 때 빌드 시점에 생성되지 않은 페이지를 서버 사이드에서 동적으로 생성한다.
  • fallback: 'blocking': 지정되지 않은 경로를 처음 요청할 때 서버 사이드에서 페이지를 생성하고, 완전히 생성된 후에 페이지를 반환한다.

True와 Blocking의 차이

true는 클라이언트 사이드에서 렌더되며 저장되지 않는다. 로딩바가 보일 확률이 높다.

Blocking은 서버사이드에서 프리렌더되며 저장된다. 로딩바가 보이지 않는다.

빌드에 저장되기 때문에 다시 한 번 더 접속할 때는 저장된 페이지를 바로 반환한다.

 

params배열과 fallback이외의 속성을 추가한다면?

만약 params객체배열과 fallback 이외의 다른 속성들을 추가한다고 해도 Next.js는 이를 무시한다.

 

getStaticPaths와 정적 생성의 예제

// pages/posts/[id].js

// getStaticPaths의 정적 생성 데이터 가져오기
export async function getStaticPaths() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const posts = await res.json();

  // 빌드 시 생성할 경로를 정의
  const paths = posts.map(post => ({
    params: { id: post.id.toString() },
  }));

  return { paths, fallback: false };
}

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

  return { props: { post } };
}

export default function Post({ post }) {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </div>
  );
}

 

2. 서버 사이드 렌더링 (Server-side Rendering)

서버 사이드 렌더링은 각 요청마다 HTML을 생성하는 방식이다.

이 방식은 매 요청 시 서버에서 페이지를 렌더링하므로, 최신 데이터를 항상 반영할 수 있다.

서버 사이드 렌더링은 데이터가 자주 변경되거나, 사용자별로 다른 데이터를 제공해야 하는 페이지에 적합하다.

서버 사이드 렌더링의 예제

서버 사이드 렌더링은 getServerSideProps 함수를 사용하여 데이터를 가져올 수 있다.

props 배열안에 props를 pre-fetching한 데이터를 넣어준다.

// pages/index.js

// 서버 사이드 렌더링 데이터 가져오기
export async function getServerSideProps() {
  // 외부 API에서 데이터를 가져옴
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const posts = await res.json();

  return {
    props: {
      posts,
    },
  };
}

export default function Home({ posts }) {
  return (
    <div>
      <h1>Posts</h1>
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

 

 

요약

  • 정적 사이트 생성 (Static Site Generation): 빌드 시 HTML을 생성하며, 모든 요청에 대해 동일한 HTML을 제공한다. getStaticProps와 getStaticPaths를 사용한다.
  • getStaticPaths: 정적 생성 시 동적 경로를 사용하려면 getStaticPaths를 사용하여 빌드 시 생성할 경로를 정의한다.
  • 서버 사이드 렌더링 (Server-side Rendering): 각 요청마다 HTML을 생성하여 최신 데이터를 반영한다. getServerSideProps를 사용한다.

Next.js의 프리 렌더링을 통해 최적의 성능과 SEO를 구현할 수 있으며, 페이지의 요구 사항에 따라 정적 생성 또는 서버 사이드 렌더링 중 적합한 방식을 선택할 수 있다.