- 원문 제목: Router cache and request memoization
- 원문 링크: https://dev.to/peterlidee/router-cache-and-request-memoization-3gi1
- 정리일: 2026-04-17 KST
- 정리 방식: 원문 저작권을 존중해 전문 번역 대신 한국어 상세 요약 제공
이 글은 Next.js App Router 캐싱을 이해할 때 가장 헷갈리는 두 층인 router cache와 request memoization을 분리해서 설명한다. 핵심은 둘 다 "같은 데이터를 다시 요청하지 않게 해준다"는 공통점이 있지만, 수명과 적용 범위가 완전히 다르다는 점이다.
- 이미 방문한 route segment를 브라우저 메모리에 저장해서 뒤로 가기, 앞으로 가기, 링크 이동을 거의 즉시 처리하려는 목적이다.
- layout과 loading state는 적극적으로 재사용되고, page는 기본적으로 완전 캐시라기보다 history navigation에서 재사용되는 쪽에 가깝다.
- 새로고침하면 사라진다. 즉, 세션 메모리 성격이 강하다.
- prefetch 방식과 정적/동적 여부에 따라 보존 시간이 달라진다. 기본 prefetch는 동적 페이지에서 짧고,
prefetch={true}나router.prefetch()를 쓰면 정적/동적 모두 더 오래 유지된다.
revalidatePath,revalidateTag,cookies.set/delete같은 서버 측 조작은 router cache를 무효화할 수 있다.- 클라이언트에서는
router.refresh()로 현재 라우트 캐시를 날리고 새 서버 응답을 강제로 받는다. - 실무 포인트는 "mutation 이후 화면이 왜 안 바뀌지?" 문제가 생기면 data cache만 볼 게 아니라 router cache도 같이 봐야 한다는 점이다.
- 같은 render pass 안에서 동일한
fetch(url, options)가 여러 번 호출되어도 실제 네트워크 요청은 1번만 보내고 결과를 재사용한다. - 서버 컴포넌트에서만 동작한다. route handler에서는 동작하지 않는다.
- GET 요청에만 적용된다.
- 수명은 한 요청이 끝날 때까지다. 다음 요청으로 넘어가면 memoization은 비워진다.
- request memoization은 "한 요청 안에서 중복 fetch 제거"다.
- data cache는 요청 사이를 넘어 유지되는 더 긴 캐시다.
- Next는 같은 fetch를 만나면 먼저 memoization을 보고, 없으면 data cache를 본다. 그래서 같은 요청 안에서는 fetch를 여러 번 써도 생각보다 부담이 적다.
작성자는 cache 옵션과 next.revalidate 값을 다르게 준 동일 URL fetch를 여러 번 호출했는데도, 실제 API hit는 1번만 발생하는 상황을 확인했다. 즉, 이론적으로는 옵션 차이가 중요하지만, 실제 구현에서는 React/Next의 dedupe가 더 공격적으로 작동하는 구간이 있다. 실무에서는 "같은 요청을 여러 컴포넌트에서 불러도 괜찮다"는 자신감을 주는 대신, 캐시 파일이 왜 저렇게 생겼는지는 기대보다 덜 직관적일 수 있다는 뜻이다.
- App Router에서 캐시 버그를 볼 때는
client cache / request memoization / data cache를 각각 따로 생각해야 한다. - 서버 컴포넌트에서 동일 fetch를 반복하는 패턴은 지나치게 겁낼 필요가 없다.
- mutation 이후 stale UI가 보이면
revalidatePath와router.refresh()역할 분담을 먼저 점검하는 게 빠르다.