next.jsfrontend
Next.js ISR 때문에 조회수가 멈춘 것처럼 보였다
조회수 기능을 붙였는데 "조회수가 안 쌓인다"는 제보를 받았다. DB를 보니 잘 쌓이고 있었다. 범인은 ISR이었다.
무슨 일이 있었나
글 상세 페이지에 이렇게 선언돼 있었다.
export const revalidate = 300; // 5분
ISR(Incremental Static Regeneration)은 페이지를 미리 렌더해두고 재검증 주기 동안 같은 HTML을 재사용한다. DB의 조회수는 올라가는데, 사용자가 보는 숫자는 최대 5분 전 스냅샷인 것.
데이터 성격에 따라 갈라치기
이 페이지엔 성격이 다른 데이터가 섞여 있었다.
| 데이터 | 신선도 요구 | 전략 |
|---|---|---|
| 글 본문 | 낮음 (수정 드묾) | ISR 유지 |
| 조회수 | 높음 (방금 내가 올렸는데!) | 클라이언트에서 갱신 |
| 좋아요 | 높음 + 인터랙션 | 클라이언트 상태 + 서버 액션 |
본문 때문에 revalidate를 버리기는 아깝다. 그래서 조회수만 클라이언트로 뺐다 — 방문 비콘이 증가된 값을 응답으로 돌려주고, 화면은 그걸로 즉시 갱신한다.
useEffect(() => {
fetch(`/api/posts/${postId}/view`, { method: "POST" })
.then((r) => r.json())
.then((j) => setViewCount(j.views)); // ISR 스냅샷 무시
}, [postId]);
교훈
- ISR은 "페이지 단위" 캐시다. 페이지 안에 실시간 데이터가 하나라도 있으면 그 부분만 분리해야 한다
- 서버 액션의
revalidatePath는 다음 요청부터 반영이다. "지금 화면"은 클라이언트 상태로 처리 - 캐시 버그의 특징은 "코드는 맞는데 화면이 틀린" 것 — DB부터 확인하면 절반은 푼 것이다
조회 1