Next.js 캐시 이해하기 (5부)

발행: (2026년 3월 28일 PM 09:24 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

베이커리 비유 (API 데이터 vs 페이지)

Next.js 애플리케이션을 베이커리라고 생각해 보세요.

  • **API 데이터(데이터 캐시)**는 데이터베이스나 외부 API에서 가져오는 원재료(밀가루, 설탕, 달걀)입니다.
  • **페이지(전체 라우트 캐시)**는 진열창에 놓인 완전히 구워진 케이크입니다.

Next.js는 완성된 HTML(케이크)만 캐시하는 것이 아니라 원시 JSON(재료)도 캐시합니다. 이는 서로 다른 위치에서 50명의 사용자가 동시에 사이트를 방문하더라도 Next.js가 데이터베이스에 50개의 쿼리를 날리지 않고, 캐시된 재료를 사용해 모두에게 즉시 제공한다는 뜻입니다.

캐시의 4가지 레이어

가장 흔히 혼동되는 부분은 사용자가 새로 고침 버튼을 눌렀을 때 무슨 일이 일어나는가 입니다. 아래는 Next.js 캐시의 네 레이어를 주방 비유와 함께 설명합니다.

1. 요청 메모이제이션 (카운터탑/클립보드)

같은 페이지에 있는 세 개의 서로 다른 React 컴포넌트가 모두 fetch('/api/user')를 호출하면, Next.js는 요청을 중복되지 않게 처리합니다: 네트워크 요청을 한 번만 수행하고 결과를 공유합니다.

Note: 카운터탑/클립보드는 각 페이지 렌더링이 끝날 때마다 깨끗이 닦아냅니다.

2. 라우터 캐시 (고객의 접시)

사용자가 앱을 탐색할 때 Next.js는 React Server Component 페이로드를 브라우저 메모리에 저장합니다. 이 덕분에 뒤로 가기 버튼을 클릭하면 즉시 반응합니다.

Note: 이 캐시는 강제 새로 고침에서는 살아남지 못합니다; 새로 고침 시 브라우저 메모리가 초기화됩니다(접시를 씻는 것과 같습니다).

3. 데이터 캐시 (식료품 저장실)

Next.js는 데이터베이스에서 반환된 원시 JSON 데이터를 여러 사용자 세션에 걸쳐 저장합니다.

Note: 이 캐시는 새로 고침을 견뎌냅니다. 페이지가 새로 고침될 때 브라우저는 서버에 새로운 데이터를 요청하지만, 서버는 식료품 저장실에서 동일한 캐시 데이터를 꺼내 제공합니다. 그래서 새로 고침을 해도 오래된 데이터가 “고쳐지지” 않는 경우가 많습니다.

4. 전체 라우트 캐시 (진열창)

Next.js는 캐시된 데이터와 컴포넌트를 사용해 빌드 시점에 순수한 정적 HTML로 렌더링합니다.

Note: 이 캐시도 새로 고침을 견뎌냅니다. 기본 데이터 캐시가 명시적으로 무효화될 때까지 사전 렌더링된 HTML 파일을 제공하기 때문입니다.

캐시 제어하기

캐시는 성능에 굉장히 유리하지만, 동적인 앱은 동적인 데이터가 필요합니다. 여기서는 Next.js에게 오래된 재료를 버리도록 지시하는 방법을 소개합니다.

1. 완전 비활성화 (캐시 사용 안 함)

데이터가 지속적으로 변하는 경우(예: 실시간 주식 티커나 은행 계좌 잔액) fetch 요청을 전혀 캐시하지 않도록 설정합니다:

// 매 요청마다 새로 가져옴
const res = await fetch('https://api.example.com/data', {
  cache: 'no-store',
});

2. 시간 기반 재검증 (Stale‑While‑Revalidate)

특정 시간 동안 캐시를 유지하고, 그 뒤에 백그라운드에서 새 데이터를 가져오도록 Next.js에 지시합니다:

// 이 데이터를 3600초(1시간)마다 재검증
const res = await fetch('https://api.example.com/data', {
  next: { revalidate: 3600 },
});

3. 필요 시 재검증 (“Invalidate” 버튼)

사용자가 폼을 제출했을 때(예: 프로필 업데이트) 해당 페이지의 캐시를 즉시 비워야 합니다. 서버 액션 내부에서 다음과 같이 수행합니다:

'use server';
import { revalidatePath } from 'next/cache';

export async function updateProfile(formData) {
  await db.user.update(formData);

  // 이 라우트에 대한 캐시된 HTML과 데이터를 버리도록 Next.js에 알림
  revalidatePath('/profile');
}

대단원의 막

이 다섯 편의 글을 통해 “신선함 vs 오래됨” 이론을 이해하는 단계에서 HTTP 헤더 마스터, React‑Query/Redux 클라이언트 상태 다루기, 그리고 최종적으로 Next.js 서버 캐시 정복까지 이뤄냈습니다.

캐시는 이제 단순한 백엔드 최적화가 아니라 프론트엔드 사용자 경험의 심장 박동과도 같습니다. 이를 마스터하면 서버 비용을 절감하면서도 즉각적인 느낌을 주는 애플리케이션을 만들 수 있습니다.

이제 빠른 무언가를 만들어 보세요.

0 조회
Back to Blog

관련 글

더 보기 »