Caching
in Frontend / Next
캐싱 이해 및 구성하기
Request Memoization | Data Caching | Full Route Cache | Router Cache |
---|---|---|---|
같은 config 요청은 저장해둠 | revalidation 전 까지 같은 데이터 사용 | stores HTML & RSC at build time | RSC payload 브라우저 메모리에 저장 |
cache only persists during request duration | persists until revalition (manually or set time) | persist until related data cache is revalidated | fast page transition cuz no server request needed |
Data Caching
- no cache
const res = await fetch("https://api.example.com/data", {
cache: "no-store", // no-cache, reload, force-cache, only-if-cached
});
- set cache time
const res2 = await fetch("https://api.example.com/data", {
next: {
revalidate: 10, // seconds
},
});
Cache-Control
- 이렇게 Export만 해주면 페이지마다 적용됨
export const revalidate = 10;
export const dyanmic = "force-dynamic"; // refetch every time
unstable_noStore
- force dyanmic 보다 권장
전체 페이지가 아닌, 개별 컴포넌트에 적용 가능
import { unstable_noStore as noStore } from 'next/cache'; const TempComponent = () => { unstable_noStore(); return ( ... ) }
Full Route Cache
- next는 빌드 시점에 전체 페이지 (dynamic routes 제외)를 pre렌더링하여 HTML과 RSC를 저장함
pre rendered AT BUILD TIME
제외방법: (○ -> λ 로 변경)
- force-dynamic
export const dynamic = 'force-dynamic'; export const Component...
- revalidatePath
export const Component => () { const createMessage = async (params) => { "use server"; addMessage(message); revalidatePath("/message", 'layout') // 2번쨰 인자 냅두면 page만 revalidate revlaidatePath("/my") // 여러개 가능 } return (..) }
- revalidateTag
export const Component => () { const response = await fetch("https://api.example.com/data", { next: { tags: ["message"] }, }); const createMessage = async (params) => { "use server"; addMessage(message); revalidateTag("message") } return (..) }
- \(\circ\) (Static) pre-rendered at build time
- \(\lambda\) (Dynamic) server-rederend on demand using Node.js
react cache
- 함수 캐싱 라이브러리
import { cache } from "react";
export const getMessages = cache(async () => {
const res = await fetch("https://api.example.com/data");
return res.json();
});
next cache
- next가 알게되는 캐시
import { unstable_cache } from "next/cache";
import { cache } from "react";
// Promise를 반환하는 함수를 캐싱
export const getMessages = unstable_cache(
cache(async () => {
const res = await fetch("https://api.example.com/data");
return res.json();
}),
["message"], // Cache Keys (not tags)
{
revalidate: 10,
tags: ["messageTag"], // Cache Tags
}
);
layout: post title: Caching description: > 캐싱 이해 및 구성하기 categories: next accent_color: “#FFF” accent_image: background: “#000” theme_color: “#000” sitemap: false permalink: /frontend/next/caching —
Request Memoization | Data Caching | Full Route Cache | Router Cache |
---|---|---|---|
같은 config 요청은 저장해둠 | revalidation 전 까지 같은 데이터 사용 | stores HTML & RSC at build time | RSC payload 브라우저 메모리에 저장 |
cache only persists during request duration | persists until revalition (manually or set time) | persist until related data cache is revalidated | fast page transition cuz no server request needed |
Data Caching
- no cache
const res = await fetch("https://api.example.com/data", {
cache: "no-store", // no-cache, reload, force-cache, only-if-cached
});
- set cache time
const res2 = await fetch("https://api.example.com/data", {
next: {
revalidate: 10, // seconds
},
});
Cache-Control
- 이렇게 Export만 해주면 페이지마다 적용됨
export const revalidate = 10;
export const dyanmic = "force-dynamic"; // refetch every time
unstable_noStore
- force dyanmic 보다 권장
전체 페이지가 아닌, 개별 컴포넌트에 적용 가능
import { unstable_noStore as noStore } from 'next/cache'; const TempComponent = () => { unstable_noStore(); return ( ... ) }
Full Route Cache
- next는 빌드 시점에 전체 페이지 (dynamic routes 제외)를 pre렌더링하여 HTML과 RSC를 저장함
pre rendered AT BUILD TIME
제외방법: (○ -> λ 로 변경)
- force-dynamic
export const dynamic = 'force-dynamic'; export const Component...
- revalidatePath
export const Component => () { const createMessage = async (params) => { "use server"; addMessage(message); revalidatePath("/message", 'layout') // 2번쨰 인자 냅두면 page만 revalidate revlaidatePath("/my") // 여러개 가능 } return (..) }
- revalidateTag
export const Component => () { const response = await fetch("https://api.example.com/data", { next: { tags: ["message"] }, }); const createMessage = async (params) => { "use server"; addMessage(message); revalidateTag("message") } return (..) }
- \(\circ\) (Static) pre-rendered at build time
- \(\lambda\) (Dynamic) server-rederend on demand using Node.js
react cache
- 함수 캐싱 라이브러리
import { cache } from "react";
export const getMessages = cache(async () => {
const res = await fetch("https://api.example.com/data");
return res.json();
});
next cache
- next가 알게되는 캐시
import { unstable_cache } from "next/cache";
import { cache } from "react";
// Promise를 반환하는 함수를 캐싱
export const getMessages = unstable_cache(
cache(async () => {
const res = await fetch("https://api.example.com/data");
return res.json();
}),
["message"], // Cache Keys (not tags)
{
revalidate: 10,
tags: ["messageTag"], // Cache Tags
}
);