cacheTag
cacheTag 함수는 캐시된 데이터를 태그로 관리해서 필요한 순간에만 캐시를 지우거나 갱신할 수 있게 도와줘요. 태그를 캐시 항목에 붙여두면, 전체 캐시를 지우는 대신 특정 태그가 붙은 데이터만 골라서 재검증하거나 삭제할 수 있답니다. 이 기능 덕분에 캐시 관리가 훨씬 스마트해지고 효율적이죠!
사용 방법
cacheTag를 사용하려면, 먼저 프로젝트의 next.config.js
파일에서 dynamicIO
플래그를 활성화해야 해요. 이렇게요:
// next.config.js
module.exports = {
experimental: {
dynamicIO: true,
},
};
dynamicIO
옵션은 아직 실험적인 기능이라, 안정성이 필요한 프로젝트에서는 신중하게 적용하는 게 좋아요.
이 설정을 한 다음, 원하는 캐시 데이터에 태그를 달아서 관리할 수 있습니다.
참고로 더!
- 태그 관리 덕분에 특정 부분만 업데이트해야 할 때, 서버 성능과 사용자 경험이 크게 개선됩니다.
- 이 기능은 특히 데이터가 자주 바뀌면서도 전체를 다시 로드하는 건 비효율적인 서비스(예: 뉴스 피드, 실시간 데이터 보여주는 앱 등)에 유용해요.
cacheTag
를 사용하면서 동시에 어떻게 캐시 무효화 전략을 세울지 고민해보면 프로젝트의 퍼포먼스 최적화에 큰 도움이 됩니다.
필요하면 다음에 캐시 사용 예제에 대해서도 알려줄게요!
Next.js에서 새롭게 제공하는 캐시 태그(cacheTag) 기능을 재미있게 활용해볼까요? 이번에 소개할 코드는 캐시를 더 세밀하게 관리할 수 있게 도와주는 설정과 함수예요.
1. next.config.js 설정
먼저 next.config.js
파일에서 실험적 기능인 dynamicIO
를 활성화해야 해요. 이 옵션을 켜면 Next.js가 새로운 캐시 태그 기능을 사용할 수 있도록 준비된답니다.
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
experimental: {
dynamicIO: true,
},
};
export default nextConfig;
여기서 dynamicIO
는 아직 완전히 안정화된 기능은 아니지만, 캐시 제어나 데이터 페칭에 좀 더 유연한 방식으로 접근할 수 있게 해줘요.
2. 캐시 태그 지정하기 - cacheTag
이제 함수 안에서 cacheTag
함수를 써보죠! 이 함수는 하나의 문자열 태그, 혹은 문자열 배열로 캐시 태그를 지정할 수 있어요.
import { unstable_cacheTag as cacheTag } from "next/cache";
export async function getData() {
"use cache";
cacheTag("my-data");
const data = await fetch("/api/data");
return data;
}
- 먼저 함수 최상단
'use cache'
디렉티브를 호출해 캐시 기능을 활성화해줍니다. cacheTag('my-data')
로 해당 함수가 사용하는 캐시 태그를 지정하죠.- 이렇게 하면
my-data
라는 태그를 기준으로 캐싱되고, 이 태그만 선택적으로 무효화할 수 있습니다.
이게 뭐가 좋느냐면, 데이터를 전체 페이지가 아니라 세부 단위별로 새로고침할 수 있다는 점이에요. 예를 들어, 특정 API 데이터를 업데이트해야 할 때 전체 페이지를 빌드할 필요 없이 해당 데이터만 캐시를 지우고 재생성할 수 있게 되는 거죠.
3. 캐시 무효화 (Cache Purge) - revalidateTag
캐시가 오래되었거나, 데이터를 리프레시하려면 태그 단위로 캐시를 무효화하는 게 중요한데요. Next.js는 revalidateTag
API로 이걸 쉽게 지원합니다.
import { revalidateTag } from "next/cache";
export async function POST() {
// 예: API 라우트에서 데이터가 변경될 때 해당 캐시 태그를 무효화
await doDataUpdate();
revalidateTag("my-data");
return new Response('Cache cleared for "my-data" tag');
}
- 위 예시처럼, 서버측 함수에서 데이터 수정 후
revalidateTag('my-data')
를 호출하면'my-data'
관련된 캐시가 모두 무효화됩니다. - 그러면 다음 요청 시점에 다시 최신 데이터를 받아서 캐쉬를 갱신하게 되죠.
요약
기능 | 설명 |
---|---|
experimental.dynamicIO | Next.js에서 캐시 태그 사용을 위한 실험적 설정 |
cacheTag | 함수 내에서 캐시 태그를 지정, 데이터 단위별 캐시 제어 가능 |
revalidateTag | 특정 태그에 해당하는 캐시를 서버에서 강제로 무효화 |
한마디
이번에 소개한 캐시 태그 기능은 특히 데이터가 자주 업데이트되는 상황에서 유용해요. API 응답이나 UI 컴포넌트의 일부를 효과적으로 갱신할 수 있으니, 무조건 페이지 전체를 다시 빌드하는 구조에서 벗어나고 싶다면 한 번 꼭 시도해보세요. 실험적이라 공식 문서와 버전이 바뀌는지는 꾸준히 체크하는 것도 잊지 마시고요!
더 궁금한 점 있으면 언제든 댓글로 남겨주세요. 같이 공부해봐요! 😊
위 코드는 Next.js의 서버 컴포넌트에서 캐시를 제어할 때 사용하는 예제입니다. 여기서 핵심은 revalidateTag라는 함수로 특정 캐시 태그를 재검증(revalidate)해서, 데이터가 바뀌었을 때 최신 상태로 유지하게 만드는 거예요.
"use server";
import { revalidateTag } from "next/cache";
export default async function submit() {
await addPost(); // 새로운 포스트를 추가하는 비동기 함수
revalidateTag("my-data"); // 'my-data'라는 태그가 붙은 캐시를 재검증해서 최신으로 업데이트
}
위 코드에서 addPost()가 끝나면, 'my-data'라는 태그를 가진 캐시는 재검증돼서 이전 데이터가 아닌 새 데이터를 가져오도록 만드는 역할이에요.
알아두면 좋은 팁
내용 | 설명 |
---|---|
Idempotent Tags | 동일한 태그를 여러 번 적용해도 추가적인 효과가 없어요. 중복 적용해도 무방해요. |
Multiple Tags | 한 캐시 엔트리에 여러 태그를 붙일 수 있어요. 배열 형태로 태그들을 넘겨주면 됩니다. |
예를 들어 이렇게 사용해요:
cacheTag("tag-one", "tag-two");
위와 같이 여러 태그를 한 번에 붙이면, 이 캐시 항목이 두 가지 태그에 묶여서 둘 중 하나라도 변경될 경우 재검증됩니다.
개인적으로 추가로 알려드릴 점!
캐시 태그를 이렇게 사용하면 무조건 캐시 무효화(invalidation)를 하느니, 필요한 부분만 선별적으로 업데이트하는 '스마트 캐싱' 전략을 세우기 좋아요. 데이터가 자주 변하는 서비스에서는 서버 성능과 유저 경험을 둘 다 잡기 위해 꼭 익혀야 하는 기능입니다.
Next.js 13+ 버전에서 제공하는 이 기능을 잘 활용하면, SSR(Server Side Rendering) 혹은 ISR(Incremental Static Regeneration) 환경에서도 원하는 타이밍에 효율적으로 데이터를 업데이트할 수 있어요. 번거로운 캐시 조작을 줄이고, 최신 데이터도 놓치지 않게 해주는 아주 쓸모 있는 기능이죠!
필요하시면 addPost() 같은 함수 내부 구현도 같이 다뤄볼테니, 언제든 질문 주세요!
예제
컴포넌트나 함수에 태그 달기
캐시된 함수나 컴포넌트 안에서 cacheTag
를 호출해서 캐시 데이터를 태그할 수 있어요. 이렇게 하면 캐시 관리가 좀 더 편리해지고, 특정 태그를 기준으로 캐시를 재검증하거나 삭제할 수 있답니다.
import { unstable_cacheTag as cacheTag } from "next/cache";
interface BookingsProps {
type: string;
}
export async function Bookings({ type = "haircut" }: BookingsProps) {
"use cache";
cacheTag("bookings-data");
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`);
return data;
}
return; //...
}
여기서 중요한 포인트는 'use cache'
라는 디렉티브를 함수 최상단에 써서 이 함수가 캐싱 기능을 사용할 거라고 알려준다는 점이에요. 그리고 cacheTag('bookings-data')
를 호출해서 이 함수가 반환하는 데이터에 bookings-data
라는 태그를 붙이는 거죠.
이렇게 태그를 달아두면, 나중에 bookings-data
태그가 붙은 캐시들을 한꺼번에 무효화하거나 업데이트할 때 훨씬 편리해져요.
또한 참고할 점은, 이 기능이 아직 불안정(unstable
)한 API이므로, 앞으로 변경될 가능성이 있다는 점이에요. 그래도 Next.js 같은 최신 프레임워크에서 제공하는 기능을 미리 써보면서 경험해보는 것도 좋겠죠?
추가로, 만약 다양한 타입의 예약 데이터를 관리해야 한다면 태그 이름을 bookings-data:${type}
같은 식으로 동적으로 생성하는 것도 좋은 방법이에요. 이렇게 하면 특정 타입만 골라서 캐시를 제어할 수 있거든요!
외부 데이터로부터 태그 만들기
비동기 함수(async function)에서 반환된 데이터를 이용해서 캐시 항목에 태그를 붙일 수 있어요.
import { unstable_cacheTag as cacheTag } from "next/cache";
interface BookingsProps {
type: string;
}
export async function Bookings({ type = "haircut" }: BookingsProps) {
async function getBookingsData() {
"use cache"; // 캐시 활용을 위한 지시어
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`);
cacheTag("bookings-data", data.id); // 받은 데이터의 id를 태그값으로 지정
return data;
}
return; //...
}
여기서 중요한 포인트는 cacheTag
를 사용해 데이터를 태그함으로써 특정 조건에 따라 캐시를 더 정밀하게 관리할 수 있다는 거예요. 예를 들어, 예약 타입별로 캐시를 구분하거나 데이터 ID별로 캐시 무효화를 쉽게 할 수 있죠.
그리고 use cache
라는 키워드가 보이죠? 이건 Next.js가 이 함수 결과를 캐싱하도록 알려주는 역할을 합니다. 실제 프로젝트에서는 이렇게 재사용 가능한 데이터를 효율적으로 다룰 때 꼭 활용해보세요!
태그된 캐시 무효화하기
작성한 태그를 기반으로 캐시를 무효화해 특정 데이터가 변경되었을 때 최신 상태를 유지할 수 있어요.
import { unstable_invalidateCacheTag as invalidateCacheTag } from "next/cache";
export async function invalidateBookingCache(id: string) {
// 'bookings-data'라는 태그에 id 값으로 붙인 캐시를 무효화합니다.
invalidateCacheTag("bookings-data", id);
}
이렇게 태그 단위로 캐시를 무효화하면, 불필요한 전체 캐시 초기화 없이 원하는 부분만 갱신 가능해져서 효율적이에요. 만약 데이터 변경 이벤트가 발생하면 이 함수를 호출해 관련 캐시를 리프레시하는 방식으로 활용하면 됩니다.
캐시 태그 활용법은 Next.js 13버전 이후의 캐시 전략에서 굉장히 강력한 기능 중 하나이니 꼭 익혀두세요! 개발하며 때때로 캐시 데이터가 꼬일 때 이 방법으로 깔끔하게 관리할 수 있습니다.
'revalidateTag'를 사용하면 필요한 시점에 특정 태그의 캐시를 무효화해서 최신 데이터를 반영할 수 있어요. 예를 들어, 아래 코드처럼 'bookings-data'라는 태그에 달려있는 캐시를 갱신해줄 수 있죠.
"use server";
import { revalidateTag } from "next/cache";
export async function updateBookings() {
await updateBookingData();
revalidateTag("bookings-data");
}
간단히 말해, updateBookingData() 함수가 예약 데이터를 업데이트한 뒤에 revalidateTag('bookings-data')를 호출하면, Next.js가 그 태그에 연결된 캐시를 무효화해서 사용자들에게 최신 정보를 보여주게 됩니다.
여기서 중요한 점은, 캐시 무효화를 태그 단위로 관리할 수 있다는 거예요. 덕분에 전체 페이지 캐시를 다 날리지 않고도, 특정 데이터 부분만 신속하게 업데이트할 수 있으니 효율적이죠!
추가로, revalidateTag는 서버 컴포넌트나 API 라우트 등 서버 측 코드에서만 사용 가능하다는 점도 기억해 주세요. 클라이언트 측에서는 사용할 수 없고, 반드시 'use server' directive가 있어야 합니다.