1. 정적 사이트 생성(SSG)이란 ?
SSG(Static Site Generation)는 SSR(Server Side Rendering)의 단점을 보완한 사전 렌더링 방식입니다. 페이지를 사용자의 요청 시점이 아닌 빌드 타임(build time)에 미리 렌더링해두는 방식으로, 이후 서버가 가동되고 브라우저에서 페이지 요청이 들어오면 이미 생성된 HTML을 즉시 응답합니다.
즉, npm run build 명령어로 프로젝트를 빌드할 때, 모든 SSG 페이지가 미리 한 번만 생성되며, 이후에는 절대 다시 생성되지 않습니다. 그 덕분에 사용자 입장에서는 매우 빠른 속도로 완성된 페이지를 받아볼 수 있게 됩니다.
이러한 특성 덕분에 빌드 타임에 백엔드에서 데이터를 가져오느라 시간이 오래 걸리더라도 사용자 경험에는 전혀 영향을 주지 않습니다.
왜냐하면, 이 모든 작업은 서버가 실제로 가동되기 전인 빌드 시점에 한 번만 일어나기 때문입니다.
이후의 작동 방식은 SSR과 비슷합니다. 브라우저는 서버로부터 받은 HTML을 렌더링하고, JS 번들을 전달받아 실행함으로써 Hydration을 완료하고 상호작용이 가능한 완성된 페이지로 거듭나게 됩니다.
✅ SSG의 장점
- 응답 속도가 매우 빠름: 페이지가 미리 렌더링되어 있기 때문에 요청 시 즉시 응답 가능
- 사용자 경험 향상: 데이터 로딩 지연이 없음
- 서버 부하 감소: 서버가 실시간으로 페이지를 생성하지 않아도 됨
⚠️ SSG의 단점
- 최신 데이터 반영이 어려움: 빌드 이후 데이터가 변경되더라도 페이지는 갱신되지 않음
- 실시간성이 필요한 페이지에는 부적합
따라서 SSG는 블로그, 마케팅 페이지, 문서 사이트처럼 데이터 변경이 적은 정적 페이지에 적합합니다.
2. SSG 기본 예제
SSG를 적용하고 싶은 페이지에서 getStaticProps 함수를 작성하면 됩니다.
export const getStaticProps = () => {
const data = "hello"; // 서버에서 받아온 데이터라고 가정
return {
props: {
data,
},
};
};
이렇게 작성하면 해당 페이지는 빌드 시점에 데이터를 기반으로 HTML을 미리 생성하게 됩니다.
import { InferGetStaticPropsType } from "next";
export default function Home(
props: InferGetStaticPropsType<typeof getStaticProps>
) {
return <div>{props.data}</div>;
}
컴포넌트에서는 props 타입을 다음과 같이 지정합니다.
🔍 확인 포인트
export const getStaticProps = async () => {
console.log("인덱스 페이지");
(...)
}
위처럼 console.log를 삽입하면, 빌드 타임에만 실행되어야 하므로 npm run dev로 실행 중에는 새로고침 시마다 로그가 반복 출력되지만, npm run build 후 npm run start로 실행하면 한 번만 출력됩니다.
이유는 개발 모드(dev)는 개발 편의를 위해 항상 사전 렌더링을 새로 수행하기 때문입니다. 실제 SSG 동작을 확인하려면 반드시 프로덕션 모드로 실행해야 합니다.
npm run build
npm run start
빌드 중 Collecting page data → Generating static pages 단계에서 getStaticProps가 실행되고, 페이지가 정적으로 생성됩니다.
또한 페이지별 빌드 결과가 출력되는 것을 확인할 수 있습니다.
3. 빌드 결과 해석하기
SSG 방식으로 동작하도록 설정해둔 index.tsx (인덱스 페이지)의 경우에만 이런 식으로 색상이 채워진 흰색 동그라미 기호가 앞에 붙어있는 것을 확인할 수 있습니다.
그 외의 페이지에는 function 기호가 붙습니다.
Next.js 빌드 결과에는 각 페이지의 렌더링 방식이 기호로 표시됩니다.
⓵ ○ (Static) prerendered as static content
SSG와 동일한 기본 정적 페이지 (Static) - 별도 설정 없이 정적으로 렌더링
⓶ ● (SSG) prerendered as static HTML (uses getStaticProps)
SSG 페이지 - getStaticProps를 사용하여 정적 렌더링됨
⓷ ƒ (Dynamic) server-rendered on demand
SSR 페이지 - 요청 시 서버에서 동적으로 렌더링됨
✱ 예시
- pages/index.tsx → ● (SSG)
- pages/about.tsx → ○ (기본 Static)
- pages/api/hello.ts → ƒ (SSR, API Route)
4. 실제 페이지에서의 확인 예시
export default function Page() {
const [books, setBooks] = useState<BookData[]>([]);
const router = useRouter();
const q = router.query.q;
const fetchSearchResult = async () => {
const data = await fetchBooks(q as string);
setBooks(data);
};
useEffect(() => {
if (q) {
// 검색 결과를 불러오는 로직
fetchSearchResult();
}
}, [q]);
return (
<div>
{books.map((book) => (
<BookItem key={book.id} {...book} />
))}
</div>
);
}
search 페이지가 위 코드 설정으로 인해 SSG 방식으로 동작하도록 설정된 것을 확인할 수 있습니다.
🔍 네트워크 탭에서 확인
npm run start
이어서 앱을 프로덕션 모드로 가동한 후 브라우저에서 네트워크 탭을 열어보겠습니다.
브라우저의 네트워크 탭 → HTML Preview를 보면, 초기 HTML에는 검색 결과가 포함되지 않음을 확인할 수 있습니다.
이는 클라이언트에서 JS가 실행되며 검색 결과를 불러오기 때문입니다.
'📍 프로그래밍 언어 > Next.js' 카테고리의 다른 글
[ Next.js ] ISR (Incremental Static Regeneration) - 시간 기반과 주문형 재검증(On-Demand-ISR) (3) | 2025.06.11 |
---|---|
[ Next.js ] getStaticPaths의 fallback 옵션 설정하기(false/blocking/true) (2) | 2025.06.10 |
[ Next.js ] getServerSideProps로 배우는 SSR (Server Side Rendering) (0) | 2025.05.22 |
[ Next.js ] 사전 렌더링과 데이터 페칭 (React/Next 비교) (0) | 2025.05.21 |
[ Next.js ] 글로벌 레이아웃과 페이지별 레이아웃 설정하기 (1) | 2025.05.21 |