
우리 팀은 Next.js 기반으로 프론트엔드 프로젝트를 진행 중이다.
하지만 내가 속한 어드민팀에서는 주로 관리용 화면을 개발하다 보니, SSR이나 SSG, ISR 같은 Next.js의 주요 기능을 직접 쓸 일이 거의 없었다.
그래서 평소 익혀두고 싶던 기능들을 사이드 프로젝트에서 먼저 테스트해봤고
실제로 잘 작동하는 걸 확인한 기능들은 회사 코드에 적용해보기도 했다.
회사에서 쓰기 전, 개인 프로젝트인 니콘내콘에서 먼저 App Router, ISR, On-demand Revalidation 등을 적용해봤다.
구조나 캐시 갱신 흐름을 미리 개인 프로젝트에서 적용해봐서 회사 코드에도 쉽게 적용할 수 있었다.
회사 서비스 랜딩 페이지 하단에는 사용자 리뷰 영역이 있었다.
이 리뷰 데이터는 CSR로 불러오는 구조였고, DB는 매주 월요일 오후 7시쯤에 담당자가 직접 업데이트하고 있었다.
크게 문제 되는 기능은 아니었지만
검색엔진이 리뷰 내용을 못 본다는 점에서 SEO 측면에서는 확실히 손해였다.
그래서 이건 정적으로 만들어두면 더 좋을 것 같아서 ISR을 적용하기로 했다.

랜딩 페이지는 내가 맡은 부분도 아니었고, 코드도 꽤 오래전에 작성된 상태였지만, 일단 테스트 브랜치에서 혼자 ISR로 구현해봤다.
그리고 랜딩 페이지를 담당하던 팀원에게 바꿔본 이유와 적용 효과를 설명드렸다.
좋게 봐주셔서 PR도 올릴 수 있었고 PR에는 기존 CSR구조의 문제, ISR을 쓰면 좋아지는 점, SEO 관점에서 얻을 수 있는 장점을 간단하게 정리해서 넣었다.
처음엔 그냥 아래처럼 revalidation 옵션만 설정하면
“일주일마다 알아서 캐시 갱신되겠지”
라고 생각했다.
export async function getStaticProps() {
const reviewData = await fetch('https://...')
return {
props: {
reviewData,
},
revalidate: 604800, // 7일
}
}
근데 실제로 적용해보니 생각보다 신경 쓸 부분이 많았다.
revalidate: 604800으로 설정해도, ISR은 배포 시점부터 주기를 다시 세고, 페이지에 누군가 방문한 시점부터 카운트가 시작된다.cron job 같은 자동화 방법도 검토해봤지만, Next.js의 ISR 캐시 구조나 배포 환경 등을 고려하면 생각보다 손이 많이 가는 작업이었다.결국 백엔드 개발자분께 부탁드려서,
리뷰 데이터를 DB에 업데이트한 직후, Next.js의 Revalidate API를 호출하는 식으로 구조를 잡았다.
await fetch('https://사이트주소/api/revalidate?secret=xxx&path=/reviews')
이렇게 하면 매주 월요일 리뷰 데이터 업데이트가 끝난 후
정확한 타이밍에 캐시가 무효화되고 새 데이터가 생성되도록 만들 수 있었다.
처음엔 "간단하게 SEO만 챙기자"는 생각이었는데
막상 도입하고 보니 생각보다 신경 써야 할 부분이 많았다.
SEO나 로딩 속도는 개선됐지만, 운영과정에서 손이 많이 가고 때에 따라 수동 개입이 필요한 상황도 생겼다.
그래서 무조건 "좋은 도입이었다"고 말하긴 어려운 것 같다.
상황에 맞는 트레이드오프를 잘 고민해야 한다는 걸 느낀 경험이었다.
많은 것을 배웠습니다, 감사합니다.