‘라우터 캐시(Router Cache)‘는 페이지 이동 속도를 높여주는 클라이언트 사이드 캐시인데요.
우리 애플리케이션의 특성에 맞춰 유효 기간인 staleTimes를 적절히 설정하고, 필요할 때 캐시를 갱신(revalidate)해 주는 것이 핵심입니다.
라우터 캐시란 무엇일까#
라우터 캐시는 앱 라우터의 클라이언트 사이드 캐시로, 서버 컴포넌트의 렌더링 결과물인 ‘RSC 페이로드’를 사용자의 브라우저에 저장하는데요.
사용자가 링크 위에 마우스를 올리는 등 prefetch가 일어나거나, 페이지를 이동하는 ‘소프트 내비게이션(Soft Navigation)‘이 발생할 때 이 캐시가 채워지고 갱신됩니다.
과거 v14.1 이전 버전에서는 이 캐시의 유효 기간을 개발자가 직접 설정할 수 없어서 많은 불편함이 있었거든요.
하지만 이제는 우리가 직접 제어할 수 있게 되었습니다.
staleTimes로 캐시 유효 기간 설정하기#
Next.js v14.2부터 staleTimes라는 실험적인 기능이 도입되었는데요.
next.config.js 파일에서 이 값을 설정하면 라우터 캐시의 유효 기간을 우리 앱에 맞게 최적화할 수 있습니다.
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
staleTimes: {
dynamic: 10, // 동적 경로 캐시 유효 기간 (초)
static: 180, // 정적 경로 캐시 유효 기간 (초)
},
},
};
export default nextConfig;
dynamic과 static 설정은 <Link> 컴포넌트의 prefetch 속성값에 따라 다르게 적용되는데요.
v15 기준으로 prefetch 속성이 없는 동적 경로는 기본 캐시 시간이 0초, prefetch={true}인 정적 경로는 5분입니다.
대부분의 경우 우리가 주로 신경 써야 할 값은 dynamic 쪽인데요.
우리 서비스에서 캐시된 데이터가 사용자에게 얼마 동안 보여져도 괜찮은지 신중하게 고민해서 이 값을 적절하게 설정하는 것이 중요합니다.
원할 때 캐시를 무효화하는 방법#
staleTimes 외에, 우리가 원하는 특정 시점에 라우터 캐시를 강제로 무효화할 수 있는 방법도 세 가지가 있는데요.
router.refresh()호출- 서버 액션에서
revalidatePath()또는revalidateTag()호출 - 서버 액션에서
cookies.set()또는cookies.delete()호출
사용자가 데이터를 수정했을 때 캐시를 갱신해야 하는 경우가 대부분인데, 만약 서버 액션에서 revalidatePath() 같은 함수를 이미 쓰고 있다면 추가 작업은 필요 없습니다.
하지만 그렇지 않은 경우에는, 데이터 수정이 완료된 후 클라이언트 컴포넌트에서 router.refresh()를 호출해주는 방식으로 캐시를 갱신할 수 있습니다.
특히 revalidatePath() 같은 함수가 서버 캐시뿐만 아니라 클라이언트의 라우터 캐시까지 영향을 준다는 점은 직관적이지 않으니, 꼭 기억해두시는 게 좋습니다.
라우터 캐시의 중요한 특징#
라우터 캐시는 클라이언트, 즉 사용자 개개인의 브라우저에 저장되는 캐시인데요.
그래서 모든 사용자의 라우터 캐시를 서버에서 한 번에 지우는 것은 불가능합니다.
예를 들어, 한 사용자가 데이터를 수정해서 revalidatePath()가 호출되더라도, 다른 사용자들은 각자 설정된 staleTimes가 지나기 전까지는 계속해서 이전 캐시를 보게 된다는 점을 알아두어야 합니다.
문서에 없는 복잡한 동작들#
사실 라우터 캐시의 실제 동작은 공식 문서에 나온 것보다 훨씬 더 복잡한데요.
제가 파악한 몇 가지 중요한 특징은 다음과 같습니다.
‘뒤로 가기’를 할 때는
staleTimes값과 상관없이 무조건 라우터 캐시를 사용합니다.staleTimes.dynamic의 시간은 ‘캐시가 저장된 시점’ 또는 ‘마지막으로 사용된 시점’부터 계산됩니다.staleTimes.static의 시간은 오직 ‘캐시가 저장된 시점’부터만 계산됩니다.
이처럼 라우터 캐시는 미묘하고 복잡한 부분이 많기 때문에, 동작을 정확히 이해하고 사용하는 것이 중요합니다.