최근 웹 개발을 공부하다 보면 페이지를 렌더링하는 방식에 대한 고민이 많아집니다. Next.js 에서는 크게 네 가지의 렌더링 방식이 있습니다. 정적 사이트 생성(SSG), 서버 사이드 렌더링(SSR), 클라이언트 사이드 렌더링(CSR), 그리고 Incremental Static Regeneration(ISR)입니다. 이 중에서 ISR은 SSG와 SSR의 장점을 모두 활용할 수 있는 기능으로, 많은 개발자들에게 주목받고 있습니다. 간략하게 표로 정리해 보면,
방식
렌더링 시점
SEO
속도
적합한 경우
CSR
클라이언트 실행 시
불리함
중간
로그인 후 개인화 UI 등
SSR
매 요청마다 서버 렌더링
유리함
느림
자주 바뀌는 데이터
SSG
빌드 시
유리함
빠름
정적 콘텐츠 (블로그 등)
ISR
빌드 후 + 일정 주기
유리함
빠름
업데이트 간격이 있는 콘텐츠
이 표를 참고하면 각 렌더링 방식의 장단점을 이해하는 데 도움이 될 것입니다. 특히 ISR은 정적 페이지를 일정 주기로 백그라운드에서 재생성할 수 있는 기능으로, 정적 사이트 생성(SSG)과 서버 사이드 렌더링(SSR)의 장점을 결합한 것입니다. 제가 운영하는 블로그는 지금까지는 SSR 방식으로 구현되어 있었습니다. Vercel의 Edge Function과 캐싱을 적극 활용하는 SSR을 구현했지만, Vercel의
Cold Start
문제로 인해 첫 실행 시 페이지 로딩 속도가 느려지는 문제가 있었습니다. 그래서 ISR을 도입하여 페이지를 정적으로 생성하고, 일정 주기로 백그라운드에서 재생성하는 방식을 적용해 보았습니다. 이 글에서는 ISR의 개념부터 구현 방법, 고급 기능까지 자세히 알아보겠습니다.
👨💻
SSG를 사용하지 않는 이유는 제 블로그의 업데이트가 없진 않으며, 추가 콘텐츠가 비교적 빠르게 생성되기 때문입니다.
ISR을 조금 더 자세히 알아보겠습니다.
ISR은 Next.js에서 제공하는 기능으로, 이미 생성된 정적 페이지를 특정 시간 간격으로 백그라운드에서 재생성하여 최신 데이터를 반영할 수 있게 합니다. 이를 통해 전체 사이트를 다시 빌드하지 않고도 개별 페이지의 콘텐츠를 업데이트할 수 있습니다. 예를 들어, 블로그 게시물이 추가되었을 때 전체 사이트를 다시 빌드하지 않고도 새로운 게시물이 포함된 페이지를 자동으로 갱신할 수 있습니다.
ISR을 구현하기 위해서는 Next.js의 generateStaticParams함수와 revalidate 속성을 사용합니다. 이 두 가지를 조합하여 ISR을 구현할 수 있습니다.
먼저, getStaticProps를 사용하여 정적 페이지를 생성할 파라미터 목록을 정의합니다. 예를 들어, 블로그 게시물의 ID 목록을 배열로 만들어 각 게시물에 대한 정적 페이지를 생성할 수 있습니다.
그런 다음, revalidate 속성을 사용하여 페이지가 재생성되는 주기를 설정합니다. 이 속성은 초 단위로 설정되며, 지정된 시간 간격으로 페이지가 백그라운드에서 재생성됩니다.
export const revalidate = 60; // 60초마다 페이지를 재생성export const dynamicParams = true; // 동적 파라미터를 사용export async function generateStaticParams() { const posts = await fetch('https://jsonplaceholder.typicode.com/posts').then(res => res.json()) return posts.map((post) => ({ id: String(post.id), // id를 문자열로 변환 }))}const PostPage = async ({ params }: { params: Promise<{ id: string }> }) => { const { id } = await params; // const additionalData = await fetchAdditionalData(id); // 추가 데이터 fetch return ( <div> {/* <h1>{additionalData.title}</h1> 추가 데이터의 제목 표시 <p>{additionalData.body}</p> 추가 데이터의 본문 표시 */} <p>게시물 ID: {id}</p> {/* 게시물 ID 표시 */} </div> )}export default PostPage;
자 이제 빌드를 시작해 보겠습니다.
npm run build
빌드 도중, Generating static pages (0/20)와 같은 메시지가 출력됩니다. 이 메시지는 ISR을 사용하여 페이지를 생성하고 있다는 것을 나타냅니다. 페이지의 개수는 generateStaticParams에서 반환한 개수에 따라 달라집니다. 예를 들어, 20개의 게시물이 있다면 Generating static pages (0/20)와 같은 메시지가 출력됩니다. 이 메시지는 페이지가 정적으로 잘 생성되고 있음을 나타냅니다.
promleeblog의 static pages
그 후, prerendered as static HTML (uses generateStaticParams) 와 같은 메시지가 출력됩니다. 이 메시지는 페이지가 정적으로 잘 생성되었음을 나타냅니다.
이제 start 후 페이지를 열어보면, posts/1과 같은 URL로 접근할 수 있습니다. 이 URL은 generateStaticParams에서 반환한 게시물 ID에 따라 달라집니다. 예를 들어, posts/1 URL로 접근하면 첫 번째 게시물의 내용을 확인할 수 있습니다.