노트

"use cache"와 Cache Components

use cache Directive and Cache Components

프런트엔드#nextjs · 연결된 개념 9개

쉽게 말하면

'use cache'는 반찬이 알아서 다 깔리던 식당이 시킨 것만 나오는 식당으로 바뀐 것과 같아요. 캐시하고 싶은 함수나 컴포넌트에만 직접 표시를 붙여서, 의도치 않게 낡은 데이터가 보이는 일을 줄여요.

비유가 깨지는 곳 주문서에 적은 내용이 곧 캐시 키예요. 함수 인자와 바깥에서 가져다 쓴 값이 자동으로 키가 되니 인자는 직렬화할 수 있어야 하고, 쿠키·헤더는 안에서 읽지 말고 바깥에서 인자로 넘겨요.

'use cache'는 Next.js 16의 Cache Components 모델에서 async 함수나 컴포넌트의 반환값을 캐시하라고 명시하는 지시어(Directive)다. 아무것도 표시하지 않으면 매 요청 실행되고, 캐시하고 싶은 곳에만 직접 붙인다(옵트인, Opt-in).

import { cacheLife, cacheTag } from 'next/cache'
 
export async function getPromotions() {
  'use cache'
  cacheLife('hours')           // 수명
  cacheTag('promotions')       // 무효화 단위 → revalidateTag('promotions', 'max')
  return db.promotion.findMany()
}
  • 켜는 법: next.config.ts에 cacheComponents: true. 이 설정에서는 부분 사전 렌더링(PPR)이 기본 동작이 된다
  • 붙이는 곳: 데이터 함수(데이터 단위 캐시), 컴포넌트·페이지(UI 단위 캐시), 파일 맨 위(모든 export)
  • 캐시 키: 함수 인자와 바깥에서 가져다 쓴 값이 자동으로 키가 된다. 입력이 다르면 다른 항목이 생긴다. 그래서 인자는 직렬화할 수 있어야 한다
  • 쿠키·헤더 같은 요청 시점 API(Application Programming Interface)는 캐시 함수 안에서 직접 읽지 않는다. 바깥(캐시하지 않는 컴포넌트)에서 값을 꺼내 인자로 넘긴다
  • 매 요청 새로워야 하는 데이터는 캐시하지 말고 Suspense로 감싸 스트리밍한다
  • 무효화: 16부터 revalidateTag는 두 번째 인자로 cacheLife 프로필을 받는다. 무효화된 동안 낡은 값을 보여 주며 백그라운드에서 갱신한다. 내가 방금 바꾼 값을 바로 보여 줘야 하면 서버 액션 안에서 updateTag를 쓴다

옵트아웃에서 옵트인으로

  • 15까지(암묵적 캐싱): 식당에 앉으면 반찬이 다 깔리고, 안 먹을 건 "빼 주세요"라고 해야 했다. 14까지는 fetch가 알아서 캐시돼 cache: 'no-store'를 찾아 넣어야 했고, 15에서도 라우트가 자동으로 정적 렌더됐다
  • 16(명시적 캐싱): 시킨 것만 나온다. 예측할 수 있어서 의도치 않은 낡은 데이터 버그가 줄어든다

이전 모델의 네 계층은 Next.js 캐시 계층, 요청 하나 안에서만 사는 메모이제이션은 React.cache, 캐시 무효화 일반론은 읽기 캐시 전략.

출처: Next.js - Caching

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 브라우저 캐시

    한 번 받은 리소스(HTML·CSS·JS·이미지)를 브라우저가 저장해 두었다가 다시 쓰는 기능. 서버가 응답 헤더로 얼마나, 어떻게 캐시할지 알려 주고 브라우저가 그대로 따른다.

  • bfcache(뒤로·앞으로 가기 캐시)

    페이지를 떠날 때 DOM과 JS 힙까지 통째로 메모리에 얼려 두었다가, 뒤로·앞으로 가기에서 그대로 되살리는 브라우저 캐시.

  • Activity와 숨겨진 라우트 보존

    Activity는 React 19.2의 컴포넌트로, UI를 언마운트하지 않고 display: none으로 숨기면서 state와 DOM(Document Object Model)을 보존한다. 숨기는 동안 Effect는 정리(cleanup)된다. 예전 이름은 Offscreen이다.

  • next-intl과 서버 컴포넌트 친화 i18n

    next-intl은 Next.js App Router와 서버 컴포넌트를 전제로 설계된 국제화(Internationalization, i18n) 라이브러리다. 번역 메시지를 React Context가 아니라 요청 단위 설정 함수에서 읽어서, 번역만 쓰는 컴포넌트를 서버 컴포넌트로 남길 수 있다.

  • LRU 캐시와 캐시 계층 비교

    LRU(Least Recently Used) 캐시는 크기를 정해 두고, 가득 차면 가장 오랫동안 쓰지 않은 항목부터 버리는 메모리 캐시다. Node.js에서는 lru-cache 패키지가 대표적이다. 자주 쓰는 데이터는 계속 남고 안 쓰는 것만 밀려난다.

보기 옵션