🚀 Next.js 사전 렌더링(Pre-Rendering) 완벽 정리

2025. 2. 24. 15:22프론트엔드/Next JS

728x90

React에서의 데이터 로딩 문제점

React에서는 컴포넌트가 렌더링될 때 useEffect를 사용하여 데이터를 요청하는 방식이 일반적입니다.

import { useEffect, useState } from "react";

export default function Home() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch("/api/data")
      .then((res) => res.json())
      .then((result) => {
        setData(result);
        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, []);

  if (loading) return <p>로딩 중...</p>;
  return <div>{JSON.stringify(data)}</div>;
}

🔴 위 방식의 문제점

  1. 첫 번째 페인트(FCP: First Contentful Paint) 지연
    • 화면이 아무것도 없는 상태에서 데이터가 도착할 때까지 기다려야 함.
  2. 클라이언트에서만 데이터 요청이 발생
    • 서버에서 HTML을 생성하지 않고, 클라이언트에서만 데이터를 요청하기 때문에 SEO에 불리.
  3. 데이터 요청이 늦게 시작됨
    • 컴포넌트가 마운트된 후 fetch 요청을 하기 때문에 필요한 데이터를 가져오는 과정이 지연됨.

Next.js의 사전 렌더링(Pre-Rendering)

Next.js는 사전 렌더링 기능을 제공하여 위 문제를 해결합니다.
즉, 페이지를 미리 렌더링해서 HTML을 생성한 후 사용자에게 제공할 수 있습니다.

📌 사전 렌더링(Pre-Rendering) 방식 3가지

  1. SSR (Server-Side Rendering) - 요청 시 서버에서 HTML을 생성
  2. SSG (Static Site Generation) - 빌드 시 미리 HTML을 생성
  3. ISR (Incremental Static Regeneration) - SSG에 추가로 일정 시간마다 새로운 HTML을 생성

이제 각각의 방식에 대해 자세히 알아보겠습니다.


1. SSR (서버 사이드 렌더링)

📌 getServerSideProps를 사용하여 서버에서 HTML을 생성하는 방식

export async function getServerSideProps() {
  const res = await fetch("https://api.example.com/data");
  const data = await res.json();

  return { props: { data } };
}

export default function Home({ data }: { data: any }) {
  return
{JSON.stringify(data)}
;
}

🔵 SSR의 특징

장점

  • 최신 데이터를 가져올 수 있음 (실시간 데이터 반영)
  • SEO 최적화 가능 (서버에서 HTML을 만들어 제공)

단점

  • 매 요청마다 서버에서 데이터를 가져옴 → 응답 속도가 느릴 수 있음
  • 서버 부하가 증가함

🔴 SSR이 적합한 경우

  • 사용자마다 다른 데이터를 제공해야 하는 경우 (로그인한 유저마다 다른 페이지)
  • 최신 데이터가 필요할 때 (주식 가격, 뉴스 등)

2. SSG (정적 사이트 생성)

📌 getStaticProps를 사용하여 빌드 시 미리 HTML을 생성하는 방식

export async function getStaticProps() {
  const res = await fetch("https://api.example.com/data");
  const data = await res.json();

  return { props: { data } };
}

export default function Home({ data }: { data: any }) {
  return
{JSON.stringify(data)}
;
}

🔵 SSG의 특징

장점

  • 가장 빠름 (미리 생성된 HTML을 제공)
  • 트래픽이 많아도 서버 부하가 없음
  • SEO에 최적화됨

단점

  • 빌드할 때 데이터가 정해지므로 실시간 데이터 반영이 어려움
  • 데이터가 변경되면 다시 빌드해야 함

🔴 SSG가 적합한 경우

  • 블로그, 문서 사이트 (변경이 자주 일어나지 않는 페이지)
  • 제품 목록 페이지 (큰 변화가 없는 경우)

3. ISR (증분 정적 생성)

📌 revalidate 옵션을 사용하여 일정 시간마다 정적 페이지를 갱신하는 방식

export async function getStaticProps() {
  const res = await fetch("https://api.example.com/data");
  const data = await res.json();

  return { props: { data }, revalidate: 10 }; // 10초마다 페이지 업데이트
}

export default function Home({ data }: { data: any }) {
  return
{JSON.stringify(data)}
;
}

🔵 ISR의 특징

장점

  • SSG의 빠른 속도를 유지하면서 최신 데이터 갱신 가능
  • 특정 시간마다 새로운 데이터를 가져와 HTML을 업데이트

단점

  • 처음 방문한 사용자는 예전 데이터를 볼 수 있음
  • 실시간 반영이 필요한 데이터에는 적절하지 않음

🔴 ISR이 적합한 경우

  • 자주 변경되지만 즉각적인 반영이 필요하지 않은 페이지 (뉴스, 블로그)
  • 트래픽이 많고 성능이 중요한 페이지 (쇼핑몰, 인기 제품 페이지)

4. SSR vs SSG vs ISR 비교

방식 HTML 생성 시점 데이터 갱신 가능 여부 성능 서버 부하 사용 예제

SSR 요청 시 서버에서 생성 ✅ 가능 (최신 데이터 제공) 느림 높음 로그인한 사용자별 맞춤 데이터
SSG 빌드 시 생성 ❌ 불가능 (재빌드 필요) 가장 빠름 없음 블로그, 정적 페이지
ISR 빌드 시 + 일정 시간마다 갱신 ✅ 가능 (일정 주기마다 업데이트) 빠름 낮음 뉴스, 제품 목록

5. 요약

  • SSR: 요청마다 서버에서 데이터 가져오기 → 실시간 반영 O, 속도 느림, 서버 부하 높음
  • SSG: 빌드 시 데이터 가져오기 → 빠름, 트래픽 많아도 안정적, 데이터 변경 시 재빌드 필요
  • ISR: SSG + 일정 시간마다 갱신 → 빠름, 최신 데이터 일정 주기마다 반영 가능

6. 어떤 방식을 선택해야 할까?

요구 사항 추천 방식

매번 최신 데이터 필요 (로그인한 유저 정보) SSR
변경이 거의 없는 콘텐츠 (블로그, 문서) SSG
변경은 있지만 즉각 반영 필요 없음 (뉴스, 쇼핑몰) ISR

7. 결론

Next.js는 다양한 사전 렌더링 기법을 제공하여 성능을 최적화할 수 있습니다.

  • SSR: 최신 데이터를 반영하지만 느리고 서버 부하가 큼
  • SSG: 가장 빠르고 SEO에 유리하지만 데이터 변경이 어렵다
  • ISR: 성능을 유지하면서 일정 주기마다 데이터 갱신 가능

 

728x90