Next에서 fetch는 특별하다는 말을 듣고 공부를 하게 되었다.
Next fetch 공식문서: https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options
참고 블로그: https://youngme92.vercel.app/blog/nextjs-13-data-fetching
공식문서 내용에는 Next.js는 서버의 각 요청이 캐싱을 설정할 수 있도록
기본 웹 fetch() API를 확장했다고 한다.
즉 Next.js에서 서버 컴포넌트에서 fetch() 메서드를 사용하면
캐싱기능을 사용할 수 있는 것 같다.
export default async function Page() {
// 첫 번째 요청: 수동으로 무효화될 때까지 캐시
// 기본적으로 'force-cache'가 설정되어 있습니다.
const staticData = await fetch(`https://...`, { cache: 'force-cache' })
// 두 번째 요청: 매번 새로운 데이터를 가져옴
// 'no-store' 옵션을 사용하여 캐시를 사용하지 않습니다.
const dynamicData = await fetch(`https://...`, { cache: 'no-store' })
// 세 번째 요청: 10초 동안 캐시됨
// 'revalidate' 옵션을 사용하여 10초마다 데이터를 다시 가져옵니다.
const revalidatedData = await fetch(`https://...`, {
next: { revalidate: 10 },
})
return <div>...</div>
}
Next.js에서는 기본적으로 컴포넌트는 Sever component로 동작하며
리액트와는 다르게 함수 컴포넌트에 async, await 키워드를 붙여서
함수 컴포넌트내에서 비동기 처리를 할 수 있다.
해당 코드를 보아 fetch 메서드를 호출 시에 두 번째 인자로
Next에서 지정한 옵션을 사용하게 되면 캐싱기능을 이용할 수 있다.
fetch메서드 옵션
Caching Data
force-cache는 기본 옵션으로, 데이터 캐시라는 공간에서 일치하는 요청을 찾고,
신선한 데이터(Fresh)가 있으면 이를 반환,
일치하는 요청이 없거나 오래된 경우(Stale),
remote 서버에서 자원을 가져와 캐시를 업데이트함!
기본적으로 force-cache 라는 옵션이 설정되며 자동으로 캐싱처리가 되어
직접적으로 캐싱을 무효화하지 않으면 데이터를 계속해서 가지고 있는다.
정적 라우트 5분, 동적 라우트는 30초간 유지한다고 한다!
※ Next에서의 캐싱되는 동작은 굉장히 복잡하다고 함 이 부분은 공부를 더 해야겠다;
no-store라는 옵션을 사용하면 캐싱처리는 하지않게 되는데
no-store는 요청할 때마다 항상 remote 서버에서 자원을 가져오고
가져온 자원을 캐시에 저장하지 않는다.
(Next에서는 상황에 따라 캐싱되는 저장소? 상황? 다른 것 같다!)
추가로 cookies() 동적함수를 사용하면 no-store 옵션으로 동작한다고 한다!
(cookies 함수는 쿠키 정보를 가져오는 함수로 보인다!)
revalidate 옵션
fetch메소드의 {next : {revalidate : false | 0 | 초단위 숫자 }} 옵션 형태로 사용하여
리소스에 대한 캐시를 처리할 수 있는 것 같다!
즉 fetch메서드를 사용했을 때의 해당 주소 요청에 대한 캐싱처리를
직접 조작하는 것이다.
- false: 리소스를 무기한 캐시하며(revalidate: Infinity)와 같은 의미
HTTP 캐시는 시간이 지남에 따라 오래된 리소스를 제거할 수 있음. - 0: 리소스를 캐시 하지 않음.
- number (초 단위): 리소스의 캐시 수명이 최대 n초임을 지정.
tags 옵션
fetch메서드의 {next : {tage: ['캐싱할 태그값']} 옵션 형태로 사용하여
어떤 요청에 대한 캐싱할 태그값(ID값)을 내가 지정하여 조작할 수 있는 것 같다.
리소스의 캐시 태그를 설정하여 데이터는 이후
revalidateTag를 사용하여 필요에 따라 재검증될 수 있다.
사용자 지정 태그의 최대 길이는 256자이고, 최대 태그 항목 수는 64개이다.
revalidateTag는 특정 캐시 태그에 대한 캐시 된 데이터를
필요에 따라 제거할 수 있도록 한다.
이 함수는 Server Action 을통해 사용하면 지정된 캐시 태그를 무효화시킬 수 있다
"use server";
import { revalidatePath, revalidateTag } from "next/cache";
//해당 handler를 사용하여 캐시 무력화
export default function clickHandler() {
console.log("server aciton");
// 특정 경로에 대한 캐시 무력화
revalidatePath("/");
// 특정 태그에 대한 캐시 무력화
revalidateTag("/posts");
}
Revalidating Data
이 부분은 중요한데 왜냐면 아직도 이해를 못 했기 때문이다.
Next에서 캐싱된 데이터는 두 가지 방법으로 재검증된다고 한다.
- 시간 기반의 재검증: {next : {revalidate : false | 0 | 초단위 숫자 }}
일정시간이 지나면 데이터를 자동으로 재검증한다.
자주 변경되지 않고 최신성이 중요하지 않는 데이터에 유용 - 요청 기반의 재검증: revalidateTag, revailddatePath
이벤트를 기반으로 데이터를 수동으로 재검증한다.
요청형 재검증에서는 태그기반 또는 경로 기반 접근방식을 사용하여
데이터 그룹을 한 번에 재 검증할 수 있다.
가능한 한 빨리 최신 데이터를 표시하려는 경우에 유용
- 개별 fetch() 요청이 경로의 기본 재검증 시간보다 낮은
revalidate 숫자를 설정하면,해당 경로 전체의 재검증 간격이 줄어든다. - 동일한 경로에서 동일한 URL을 사용하는 두 개의 fetch 요청이 다른
revalidate 값을 갖는 경우, 더 낮은 값이 사용된다. - revalidate가 0으로 설정된 경우 캐시 옵션을 설정할 필요가 없다.
0은 cache: 'no-store'를 의미하고,
양수 값은 cache: 'force-cache'를 의미하기 때문 - { revalidate: 0, cache: 'force-cache' } 또는
{ revalidate: 10, cache: 'no-store' }와 같은 충돌하는 옵션은 오류를 발생시킴
데이터 재검증을 시도하는 동안 오류가 발생하면
마지막으로 성공적으로 생성된 데이터가 캐시 되어 계속 제공된다.
다음 후속 요청에서 NextJs는 데이터 재검증을 다시 시도된다고 한다.
또한 해당 데이터가 stale 상태로 바뀌어야 한다면 즉 현재 요청에서
stale 데이터 값으로 가져간 후에 다음요청 때 해당값을 새로 요청하여
fresh 데이터를 가져온다고 한다(Next의 caching 동작)
(쉽게 stale 데이터는 새롭게 요청하려면 다음요청 때 fresh데이터로 받아올 수 있다.)
다음번엔 Next에 Caching에 대해 공부하여 대한 글을 써볼려고 한다.
사실 Next에 fetch 메소드에 더 사용을 해봐야 이해를 할 것 같고
Next에서 Caching에 대해서도 어떻게 동작하는지에 대해 이해를 해야
쉽게 사용할 수 있을 것 같다!
https://nextjs.org/docs/app/building-your-application/caching
Building Your Application: Caching | Next.js
An overview of caching mechanisms in Next.js.
nextjs.org