Next.js의 SSG(Static Site Generation) 개념과 활용
2025. 3. 2. 23:10ㆍ프론트엔드/Next JS
728x90
Next.js의 SSG(Static Site Generation) 개념과 활용
1. SSG(Static Site Generation)란?
**SSG(정적 사이트 생성)**는 Next.js에서 빌드 시(static generation) 미리 HTML을 생성하여 정적인 페이지를 제공하는 방식입니다.
📌 주요 특징
- 빌드 시점에 HTML을 생성하므로, 빠른 페이지 로딩 속도를 제공함
- 서버 요청 없이 즉시 렌더링되므로 SEO(검색 엔진 최적화)에 유리함
- 데이터가 자주 변경되지 않는 정적인 페이지에 적합
- 사용자가 페이지를 요청하기 전에 미리 렌더링되므로 서버 부하를 줄일 수 있음
📌 getStaticProps를 사용하면 SSG 방식으로 페이지를 생성할 수 있음.
export const getStaticProps = async () => {
// 빌드 시 실행됨
};
2. getStaticProps를 활용한 도서 목록 페이지 생성
📌 예제: 정적인 도서 목록 페이지 생성
// pages/index.tsx
import SearchableLayout from "@/components/searchable-layout";
import style from "./index.module.css";
import { ReactNode } from "react";
import BookItem from "@/components/book-item";
import { InferGetStaticPropsType } from "next";
import fetchBooks from "@/lib/fetch-books";
import fetchRandomBooks from "@/lib/fetch-random-books";
// SSG를 사용하여 도서 데이터를 미리 가져옴
export const getStaticProps = async () => {
console.log("인덱스 페이지 빌드 중...");
// 두 개의 API 요청을 병렬 처리하여 데이터 가져오기
const [allBooks, recoBooks] = await Promise.all([
fetchBooks(),
fetchRandomBooks(),
]);
return {
props: {
allBooks,
recoBooks,
},
};
};
export default function Home({
allBooks,
recoBooks,
}: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<div className={style.container}>
<section>
<h3>지금 추천하는 도서</h3>
{recoBooks.map((book) => (
<BookItem key={book.id} {...book} />
))}
</section>
<section>
<h3>등록된 모든 도서</h3>
{allBooks.map((book) => (
<BookItem key={book.id} {...book} />
))}
</section>
</div>
);
}
// 페이지 전체 레이아웃 설정
Home.getLayout = (page: ReactNode) => {
return <SearchableLayout>{page}</SearchableLayout>;
};
✅ 코드 설명
- getStaticProps에서 fetchBooks()와 fetchRandomBooks()를 사용해 도서 데이터를 가져옴.
- Promise.all()을 사용하여 병렬로 API 호출을 수행하여 성능을 최적화함.
- getStaticProps에서 반환한 props가 컴포넌트에 전달되어 정적인 HTML로 미리 렌더링됨.
- Home.getLayout을 사용하여 페이지 전체에 SearchableLayout을 적용.
- console.log("인덱스 페이지 빌드 중...")는 빌드 시점에만 실행됨.
3. SSG와 검색(Query String) 처리 문제
Q. 검색어(Query String)와 같은 동적 데이터를 어떻게 처리할까?
- getStaticProps는 빌드 시점에 데이터를 가져오므로, 검색어(q)를 기반으로 데이터를 가져올 수 없음.
- SSG에서는 쿼리 스트링을 직접 사용할 수 없기 때문에, 클라이언트 측에서 데이터를 가져와야 함.
📌 해결 방법: 클라이언트에서 API 요청하여 처리
// pages/search.tsx
import SearchableLayout from "@/components/searchable-layout";
import { useRouter } from "next/router";
import { ReactNode, useEffect, useState } from "react";
import BookItem from "@/components/book-item";
import fetchBooks from "@/lib/fetch-books";
import { BookData } from "@/types";
export default function Page() {
const [books, setBooks] = useState<BookData[]>([]);
const router = useRouter();
const q = router.query.q; // URL에서 검색어 가져오기
const fetchSearchResult = async () => {
if (q) {
const data = await fetchBooks(q as string);
setBooks(data);
}
};
// 검색어가 변경될 때마다 API 요청
useEffect(() => {
fetchSearchResult();
}, [q]);
return (
<div>
{books.map((book) => (
<BookItem key={book.id} {...book} />
))}
</div>
);
}
// 페이지 전체 레이아웃 설정
Page.getLayout = (page: ReactNode) => {
return <SearchableLayout>{page}</SearchableLayout>;
};
✅ 코드 설명
- useRouter()를 사용하여 URL에서 검색어(q)를 가져옴.
- useEffect에서 fetchBooks(q)를 호출하여 검색 결과를 가져옴.
- getStaticProps 대신 클라이언트 측에서 데이터를 가져와 SSG 방식과 동적으로 데이터를 불러오는 방식을 결합.
- 검색어가 변경될 때(q가 변경될 때)마다 API 요청을 새로 보냄.
4. getStaticProps의 revalidate 옵션 활용 (ISR)
Next.js에서는 revalidate 옵션을 사용하여 일정 시간마다 정적 페이지를 재생성할 수 있음.
이를 Incremental Static Regeneration(ISR) 이라고 함.
📌 10초마다 데이터를 갱신하는 SSG 예제
export const getStaticProps = async () => {
const allBooks = await fetchBooks();
const recoBooks = await fetchRandomBooks();
return {
props: {
allBooks,
recoBooks,
},
revalidate: 10, // 10초마다 정적 페이지를 다시 생성
};
};
✅ revalidate의 동작 방식
- revalidate: 10을 설정하면 사용자가 페이지를 방문할 때마다 캐시된 페이지를 확인함.
- 10초가 지나면 새로운 요청이 들어올 때 페이지를 다시 생성.
- 기존의 SSG의 장점(빠른 로딩 속도)을 유지하면서 데이터가 업데이트되는 효과를 제공.
5. getServerSideProps와의 비교
비교 항목 getStaticProps (SSG) getServerSideProps (SSR)
| 실행 시점 | 빌드 시 | 요청 시마다 실행 |
| 로딩 속도 | 매우 빠름 (미리 생성된 정적 페이지 제공) | 느림 (매번 서버에서 데이터를 가져옴) |
| 데이터 변경 반영 | 빌드 시 고정 (ISR로 해결 가능) | 항상 최신 데이터 반영 |
| SEO 최적화 | 우수 (정적 HTML 제공) | 우수 |
| 서버 부하 | 낮음 | 높음 |
🎯 결론
- 변경되지 않는 정적 페이지는 getStaticProps를 사용하여 미리 렌더링하는 것이 좋음.
- 검색어 등 동적인 데이터는 getStaticProps 대신 클라이언트에서 API 요청하여 처리해야 함.
- 데이터가 자주 바뀌지만, 즉시 반영할 필요가 없다면 revalidate(ISR) 옵션을 사용하면 됨.
- 항상 최신 데이터를 보여줘야 하는 경우 getServerSideProps(SSR) 방식이 더 적절함.
🚀 즉, SSG는 빠른 성능과 SEO 최적화를 위한 강력한 기능이며, 동적 데이터 처리는 클라이언트에서 보완하는 것이 좋다!
728x90
'프론트엔드 > Next JS' 카테고리의 다른 글
| 📌 Next.js의 ISR(Incremental Static Regeneration) 방식 자세한 설명 (0) | 2025.03.05 |
|---|---|
| 📌 Next.js에서 getStaticProps와 getStaticPaths를 활용한 SSG 정리 (0) | 2025.03.05 |
| Next.js에서 getServerSideProps를 활용한 도서 데이터 관리 (1) | 2025.03.02 |
| React Router에서 accessToken 없을 경우 리디렉션 처리하기 (0) | 2025.03.02 |
| 백준 2206번: 벽 부수고 이동하기 - BFS 최단 거리 문제 정리 (0) | 2025.03.01 |