사전 지식
next app router의 서버 컴포넌트에서 다이나믹한 요소 cookies, params, searchParams 등등을 사용하는 동작이 없다면 SSG로 동작하여 캐싱이 강제화 된다 -> fetch option [ force cache ] . 이때 next: revalidate 와 같은 주기를 등록한다면 이는 ISR로 동작하여 주기마다 캐시에 담긴 데이터를 최신화 시켜준다.
fetch에 no-store 옵션을 명시한다면 이는 SSR 동작이 되어 요청 시점마다 서버에서 HTML을 생성해서 보내므로 SSG/ISR 보다 성능상 좋지 않다. 그래서 개인적으로 Next의 최적화를 생각하여 서버 컴포넌트는 될 수 있는 한 SSG/ISR로 할려고 노력하는 편이다.
문제 상황
제목과 같이 아이템 리스트를 보여주는 페이지가 있을 경우 상단의 서버 컴포넌트에서는 fetch를 통해 네트워크 요청으로 디비에 담긴 데이터를 가져올 수 있을 것이다. 이 때 fetch의 캐싱 옵션으로 no-store를 준다면 클라이언트가 페이지에 접근 할 때마다 배포 서버에서는 HTML을 새로 생성해서 많은 사용자가 접근 할 경우, 배포 서버는 과부하를 겪을 것이다.
이것을 최적화 하는 방법으론 fetch 의 캐싱 옵션을 사용하는 것이다. 캐싱 옵션을 명시하지 않는다면 서버 컴포넌트에서는 force-cache가 적용되어 빌드 시점에 데이터를 가져와서 html에 미리 포함 시킬 것이다. 이후 사용자들이 이 페이지에 접근하더라도 배포 서버에서는 이미 만들어진 HTML 을 보내기 때문에 배포 서버에 가해지는 부하는 SSR로 동작할 때보다 적을 것이다.
여기에서 들 수 있는 의문은 운영자나 업자들이 새로운 아이템을 디비에 추가했을 경우 유저들은 이 아이템이 추가 된 리스트 페이지를 보냐는 것이다. 왜냐하면 SSG로 동작하여 빌드 시점에 만들어진 캐싱 된 아이템들만 페이지에 보여지기 때문이다. 이는 revalidatePath나 revalidateTag 를 활용하면 해결할 수 있다.. 이는 서버에서 동작하는 배포 서버 전체 캐시를 무효화 하는 동작이다. 운영자가 새로운 데이터를 디비에 등록 한 뒤 revalidatePath를 실행하는 코드를 심어놨다면, 이후 이 동작이 실행했을 경우 next는 이것을 캐치하여 배포 서버에서 기존에 빌드로 생성 된 HTML과 데이터 캐시를 삭제한 뒤 새로운 HTML을 생성하고 이때 디비로부터 새로운 아이템들을 받아와서 캐싱한다. 따라서 빌드 된 결과물이 바꼈으니 유저들이 아이템 리스트 페이지에 접근헀을 때는 아이템이 추가 된 페이지를 볼 수 있다.
운영자 아이템 등록
↓
revalidatePath("/shop")
↓
Next.js: /shop 캐시 삭제
↓ (다음 요청 시점)
사용자 /shop 접속
↓
서버 컴포넌트 실행 + fetch("/api/shop/all")
↓
DB 최신값 가져옴
↓
Next.js 캐시에 저장 + 응답
↓
다음 사용자들은 이 캐시 활용
기존에도 POST 동작 후 성공하면 revalidatePath를 실행하고 router.refresh를 실행하여 새로운 아이템이 추가 된 리스트를 보여주도록 동작을 했지만 내부 로직을 정확히 알지 못하여 SSG/ISR+revalidatePath 와 같은 최적화 경험을 설명하지는 못했다. 그래서 이번 기회에 글을 작성해봄.
틀린 점은 피드백 해주면 감사하겠습니다
'FrontEnd > Next.js' 카테고리의 다른 글
| revalidatePath로 캐시 무효화 시 마주칠 수 있는 상황 (0) | 2025.10.02 |
|---|---|
| Next.js 로 블로그 개발하면서 겪었던 트러블 슈팅 모음 (0) | 2025.10.01 |
| 서버 컴포넌트에서 fetch와 캐싱 동작: SSR, SSG, ISR 관점에서 정리 (0) | 2025.09.13 |
| Resend로 발송 시 개발 모드에서 이메일이 오지 않는 경우 (0) | 2025.08.19 |
| [next.js] next/headers cookies로 set을 했지만 이후 undefined가 뜨는 이유 (0) | 2025.07.24 |