next.js 에서는 강력하고 공격적인 캐싱을 여러가지 제공 합니다.
이번 포스팅에서는 next.js 서버측에서 실행하는 캐싱처리 종류를 알아보겠습니다.
요청 메모이제이션은 컴포넌트 렌더링 과정에서 발생하는 중복된 API 요청을 방지하는 기능입니다.
하나의 렌더링 과정에서 동일한 요청이 여러 번 발생하면, 첫 번째 요청의 결과를 캐싱하고 이후 요청에서는 캐싱된 결과를 재사용합니다.
이를 통해 불필요한 네트워크 트래픽을 줄이고 렌더링 성능을 향상시킵니다.
예를들어 A 컴포넌트와 B 컴포넌트에서 똑같은 옵션의 요청을 한다면 캐싱처리한다.
중복 요청 감소로 네트워크 트래픽 절약
데이터 페칭 최적화로 렌더링 성능 향상
데이터 캐시는 Next.js에서 데이터를 캐싱하는 메커니즘입니다.
fetch 요청을 통해 가져온 데이터를 캐싱하여 이후 동일한 요청이 발생했을 때 캐시된 데이터를 사용합니다.
시간 기반 재검증(Time-based Revalidation) 또는 주문형 재검증(On-demand Revalidation)을 통해 캐시된 데이터를 업데이트할 수 있습니다.
데이터 재사용으로 네트워크 요청 감소
데이터 페칭 속도 향상으로 사용자 경험 개선
데이터 재검증 전략을 신중하게 선택해야 함
캐시된 데이터의 유효성을 관리해야 함
전체 경로 캐시는 빌드 시 각 경로를 렌더링하고 결과를 캐싱하는 기능입니다.
매 요청마다 렌더링하지 않고 캐시된 경로를 응답하여 페이지 로딩 속도를 향상시킵니다.
정적 생성된 페이지에 주로 적용되며, 동적 페이지는 조건에 따라 캐싱됩니다.
페이지 로딩 속도 향상으로 사용자 경험 개선
서버 부하 감소
동적 콘텐츠는 캐싱이 어려울 수 있음
캐시된 콘텐츠 업데이트 시 재빌드 필요
import Messages from '@/components/messages';
import {unstable_noStore} from "next/cache";
import {getMessages} from "@/lib/messages";
// 동일한 결과를 얻을 수 있음
// (세번째 방법)
export const revalidate = 5;
// cache : no-store 랑 같음
// (네번째 방법)
export const dynamic = 'force-dynamic';
export default async function MessagesPage() {
// 특정 컴포넌트에만 캐싱처리를 원하지 않을 때 next에서 권장사항
// (다섯번째 방법)
unstable_noStore();
// fetch 옵션으로 캐싱 처리 막기 (첫번째 방법)
const response = await fetch('http://localhost:8080/messages', {
cache: 'no-store'
});
// 아래의 구문처럼 5초동안만 캐싱된 데이터를 사용하고 이후엔 새로운 데이터를 받기
// (두번째 방법)
const response = await fetch('http://localhost:8080/messages', {
next : {
revalidate: 5
}
});
const messages = await response.json();
if (!messages || messages.length === 0) {
return <p>No messages found</p>;
}
return <Messages messages={messages} />;
}
Next.js는 다양한 캐싱 기능을 통해 개발 편의성을 높이고 성능을 최적화합니다.
하지만 공격적인 캐싱 전략은 때로는 예상치 못한 리소스 낭비나 데이터 불일치를 초래할 수 있습니다.
따라서 각 캐싱 기법의 특성을 정확히 이해하고, 프로젝트의 요구사항에 맞춰 적절한 캐싱 전략을 선택하는 것이 중요합니다.