Next.js에서 bfcache(Back-Forward Cache) 문제 해결하기
bfcache(Back-Forward Cache)는 사용자가 브라우저의 “뒤로 가기” 또는 “앞으로 가기” 버튼을 눌렀을 때, 페이지를 다시 로드하지 않고 이전 상태 그대로 복원하는 브라우저 기능이다. 하지만 Next.js의 기본 캐싱 전략은 이 기능과 충돌하여, 페이지를 다시 불러오는 문제가 발생할 수 있다.
이번 글에서는 Next.js에서 bfcache 문제를 해결하는 방법을 정리한다.
1. 문제 원인
Next.js는 기본적으로 서버 사이드 렌더링(SSR)과 동적 페이지 생성을 활용하며, 이러한 방식은 Cache-Control: no-store
와 같은 캐싱 설정을 사용해 항상 최신 데이터를 제공하도록 한다. 하지만 이 설정은 브라우저가 페이지를 완전히 다시 로드하도록 강제하며, bfcache가 활성화되지 않는 원인이 된다.
bfcache가 활성화되지 않으면:
- 뒤로 가기/앞으로 가기를 눌렀을 때 페이지가 다시 로드됨
- 사용자 경험(UX)이 저하됨
- 불필요한 네트워크 요청이 발생하여 성능이 저하됨
2. 해결 방법
✅ 1. Middleware에서 Cache-Control
헤더 설정
Next.js의 Middleware를 활용하여 Cache-Control
헤더를 변경하면 bfcache가 활성화될 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const response = NextResponse.next();
// bfcache를 위한 Cache-Control 헤더 설정
response.headers.set("Cache-Control", "public, max-age=0, must-revalidate");
return response;
}
// API 및 정적 파일을 제외한 모든 경로에 적용
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"]
};
💡 왜 Cache-Control: public, max-age=0, must-revalidate
를 사용해야 할까?
public
: 브라우저와 중간 캐시(프록시)에서 캐싱할 수 있도록 허용한다.max-age=0
: 캐시된 데이터를 바로 만료시키지만, 재검증 후 사용할 수 있다.must-revalidate
: 브라우저가 캐시된 데이터를 사용하기 전에 서버에 유효성을 확인하도록 한다.
이 설정을 적용하면 브라우저는 bfcache를 활성화하면서도 필요할 때만 데이터를 갱신하게 된다.
✅ 2. layout.tsx
에서 메타데이터 설정
metadata
를 수정하여 페이지의 메타 정보에 캐싱 설정을 추가한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
// src/app/layout.tsx
export const metadata = {
metadataBase: new URL("https://your-site.com"),
title: {
default: "Your Site",
template: "%s | Your Site"
},
description: "당신의 사이트 설명",
// Cache-Control 설정 추가
other: {
"Cache-Control": "public, max-age=0, must-revalidate"
}
};
💡 layout.tsx
에서 캐싱 설정을 추가하는 이유
metadataBase
는 정적 리소스 및 Open Graph(OG) 메타 태그의 기본 URL을 설정한다.Cache-Control
을 추가하면 페이지가 서버에서 응답할 때 캐싱 정책을 포함할 수 있다.must-revalidate
를 적용하여, 브라우저가 캐시된 페이지를 사용할지 여부를 결정할 수 있도록 한다.
3. 적용 후 기대 효과
이 설정을 적용하면: ✅ bfcache가 정상적으로 작동하여 뒤로 가기/앞으로 가기 시 페이지가 즉시 로드됨
✅ 불필요한 네트워크 요청이 줄어들어 성능이 개선됨
✅ Next.js의 동적 페이지도 최신 데이터를 유지하면서도 UX가 향상됨
4. 추가적인 고려사항
- API 경로에는 적용하지 않기
- API 응답은 최신 데이터를 유지해야 하므로
Cache-Control: no-store
를 유지해야 한다. - API 라우트에서는 개별적으로
revalidate
값을 설정하여 캐싱을 관리해야 한다.
- API 응답은 최신 데이터를 유지해야 하므로
- 정적 페이지와 동적 페이지 분리
ISR(Incremental Static Regeneration)
을 사용하는 페이지는revalidate
를 적절히 설정하여 bfcache를 방해하지 않도록 한다./blog
,/docs
등 정적 페이지는revalidate: 60
과 같은 설정을 적용하면 좋다.
- 브라우저 지원 확인
- 최신 크롬, 사파리, 파이어폭스에서는
bfcache
가 활성화되지만, 일부 구형 브라우저에서는 동작 방식이 다를 수 있다.
- 최신 크롬, 사파리, 파이어폭스에서는
5. 결론
Next.js에서 bfcache가 정상적으로 동작하지 않는 문제는 Cache-Control
설정을 조정하면 해결할 수 있다.
- Middleware에서
Cache-Control: public, max-age=0, must-revalidate
설정 layout.tsx
에서metadata.other
를 활용한 추가 설정
이렇게 설정하면 Next.js의 SSR 및 동적 데이터 관리와 함께 bfcache를 최적화하여 UX를 개선할 수 있다. 🚀