HTTP Cache와 NextJS Page Router 캐싱 정리
HTTP 캐싱에 대한 내용 정리 및 NextJS PageRouter에서 캐싱 방식에 대해서 정리했습니다.
Http 캐시
유저와 서버 간의 캐싱 상호작용
- 초기 요청: 사용자가 웹페이지에 처음 접속하면 서버는 해당 페이지의 모든 자원(HTML, CSS, JS, 이미지 등)을 응답과 함께 보냅니다. 이때 서버는 각 자원에 대해 적절한 캐시 정책을 설정해 둡니다.
- 재요청 시: 사용자가 같은 페이지에 다시 접속하면, 브라우저는 캐시에 저장된 자원을 사용하여 페이지를 로드합니다. 필요한 경우 브라우저는 서버에 조건부 요청을 보내 자원이 최신 상태인지 확인합니다.
- 캐시된 자원의 만료: 서버가 설정한 캐시 유효 기간이 지나면, 브라우저는 해당 자원을 새로 요청하게 됩니다. 이때 서버는 새 자원을 제공하거나, 자원이 변경되지 않았음을 알려 캐시를 재사용하게 할 수 있습니다.
-
Cache-Control 옵션
1.
public- 설명: 응답을 모든 캐시에 저장할 수 있음을 나타냅니다. 공유 캐시(예: CDN, 프록시 서버)와 브라우저 캐시 모두에 저장될 수 있습니다.
- 예시:
Cache-Control: public
2.
private- 설명: 응답을 단일 사용자에 대해서만 캐시할 수 있음을 나타냅니다. 브라우저 캐시에만 저장되며, 공유 캐시에는 저장되지 않습니다.
- 예시:
Cache-Control: private
3.
no-store- 설명: 응답을 전혀 캐시하지 않음을 의미합니다. 이 디렉티브는 요청 또는 응답에 대해 어떠한 캐시도 저장하지 않아야 함을 지시합니다. 요청할 때마다 항상 서버에서 새 데이터를 가져옵니다.
- 예시:
Cache-Control: no-store
4.
no-cache- 설명: 응답을 캐시에 저장할 수 있지만, 재사용 전에 서버에 검증해야 함을 의미합니다. 캐시에 저장된 데이터가 유효한지 확인하는 과정을 거칩니다.
- 예시:
Cache-Control: no-cache
5.
max-age=<seconds>- 설명: 캐시에 응답을 저장할 수 있는 최대 시간(초 단위)을 지정합니다. 이 시간이 지나면 캐시는 만료된 것으로 간주되고, 다시 서버에서 데이터를 가져오게 됩니다.
- 예시:
Cache-Control: max-age=3600(1시간 동안 캐시 가능)
6.
s-maxage=<seconds>- 설명: 공유 캐시(예: 프록시 서버)에서 응답을 저장할 수 있는 최대 시간을 지정합니다. 이 디렉티브는
max-age를 덮어씁니다. 클라이언트 측 캐시에는 적용되지 않습니다. - 예시:
Cache-Control: s-maxage=600(10분 동안 공유 캐시에 캐시 가능)
7.
must-revalidate- 설명: 캐시된 데이터가 만료되면, 반드시 서버에 검증 요청을 보내야 함을 의미합니다. 서버가 응답을 다시 확인하지 않고는 재사용할 수 없습니다.
- 예시:
Cache-Control: must-revalidate
8.
proxy-revalidate- 설명:
must-revalidate와 유사하지만, 이 디렉티브는 프록시 서버에서만 적용됩니다. 공유 캐시에서만 만료된 데이터를 다시 검증해야 함을 의미합니다. - 예시:
Cache-Control: proxy-revalidate
9.
no-transform- 설명: 중간 프록시 서버가 응답 콘텐츠를 변경하지 않도록 합니다. 예를 들어 이미지 포맷 변환 등의 작업을 허용하지 않습니다.
- 예시:
Cache-Control: no-transform
10.
immutable- 설명: 응답이 절대로 변경되지 않을 것임을 나타냅니다. 이 경우,
max-age기간 동안 캐시된 데이터를 서버에 검증하지 않고 재사용할 수 있습니다. - 예시:
Cache-Control: immutable
11.
stale-while-revalidate=<seconds>- 설명: 캐시된 데이터가 만료된 경우에도, 지정된 시간 동안 해당 데이터를 사용하면서 백그라운드에서 재검증할 수 있습니다.
- 예시:
Cache-Control: stale-while-revalidate=120(캐시가 만료된 후 2분 동안 재검증 없이 사용 가능)
12.
stale-if-error=<seconds>- 설명: 서버 오류가 발생한 경우, 지정된 시간 동안 만료된 캐시를 사용할 수 있습니다.
- 예시:
Cache-Control: stale-if-error=300(오류 발생 시 5분 동안 만료된 캐시 사용 가능)
13.
max-stale=<seconds>- 설명: 클라이언트가 만료된 캐시를 여전히 사용할 수 있는 시간을 지정합니다. 이 디렉티브는 클라이언트 측에서만 사용됩니다.
- 예시:
Cache-Control: max-stale=600(캐시가 만료된 후 10분 동안 사용할 수 있음)
14.
min-fresh=<seconds>- 설명: 캐시된 응답이 최소한 지정된 시간 동안은 유효해야 함을 나타냅니다. 이 디렉티브는 클라이언트 측에서 서버에 요청 시 사용됩니다.
- 예시:
Cache-Control: min-fresh=60(1분 이상 유효해야 함)
자주 쓰이는 옵션 설명
-
public, max-age=3153600
→ 중간 서버에도 캐싱될 수 있도록 하고, 브라우저에 1년 동안 캐싱되도록 한다. 유효성 검사는 서버에 요청하고, 바뀌지 않았으면 304를 돌려받은 뒤 캐싱된 데이터를 사용한다.
-
private
→ 중간 서버에 캐싱되지 않고, 오직 브라우저에만 캐싱될 수 있도록 한다. 서버로부터 캐싱을 얼마나 할 것인지 정해진 것이 없기 때문에 브라우저만다 다르게 동작하게 된다.
-
no-cache
→ 브라우저에 캐싱할 수 있지만, 반드시 서버에서 304 응답이 와야지만 그 캐시를 사용할 수 있다. 브라우저에 캐싱을 하지 않는다는 의미 X
-
no-store
→ 브라우저에 캐싱할 수 없음. 반드시 리소스를 요청하게 되면 서버로 매번 요청함.
-
must-revalidate
→ 캐싱이 만료되었으면 반드시 서버로 캐싱된 데이터가 유효한지 검증 받아야한다는 옵션.
-
immutable
→ 캐싱할 수 있는 시간이 명시되어 있을 때, 그 시간 동안은 서버에 유효성 검증을 하지 않고, 바로 사용할 수 있다는 것을 의미함
NextJS Page Router의 캐싱 방식
-
빌드될 때마다 파일에 고유한 이름이 생기기 때문에, 빌드할 때만 정해지는 파일은 재요청 받지 않도록 설정한다. (cache-control: public, max-age=31536000, immutable)
- html, js, css, 각종 이미지 파일들 모두 포함
cache-control 디렉티브의 의미
public:- 이 디렉티브는 응답을 모든 캐시(공유 캐시와 브라우저 캐시 모두)에 저장할 수 있음을 나타냅니다. 즉, 프록시 서버, CDN, 브라우저 등의 캐시 모두가 이 응답을 캐시할 수 있습니다.
- 이는 특정 사용자에게만 해당되는
private과 반대되는 개념으로, 모든 사용자가 동일하게 접근할 수 있는 콘텐츠에 적합합니다.
max-age=31536000:- 이 디렉티브는 캐시된 응답이 유효한 최대 시간을 초 단위로 지정합니다. 여기서
31536000초는 정확히 1년을 의미합니다. - 따라서 이 응답은 캐시에 1년 동안 저장되며, 그 기간 동안에는 서버에 다시 요청하지 않고도 캐시에서 직접 제공될 수 있습니다.
- 이 디렉티브는 캐시된 응답이 유효한 최대 시간을 초 단위로 지정합니다. 여기서
immutable:- 이 디렉티브는 응답이 절대로 변경되지 않을 것임을 나타냅니다. 즉, 이 자원은 한 번 캐시에 저장되면 유효 기간(
max-age)이 끝날 때까지 절대로 변경되지 않으므로, 클라이언트나 캐시 서버는 이를 다시 검증할 필요가 없습니다. - 이 설정은 캐시된 자원이 새로고침이나 다른 조건부 요청 없이도 재사용될 수 있도록 보장합니다.
- 이 디렉티브는 응답이 절대로 변경되지 않을 것임을 나타냅니다. 즉, 이 자원은 한 번 캐시에 저장되면 유효 기간(
-
ISR 방식으로 생성되는 페이지에 대해서는 revalidate가 중간 서버에 캐싱될 수 있는 s-max-age가 된다. (cache-control: s-maxage=10, stale-while-revalidate)
cache-control 디렉티브의 의미
s-maxage=10:- 이 디렉티브는 공유 캐시에서 응답을 캐시할 수 있는 최대 시간을 10초로 지정합니다. 이 시간 동안은 공유 캐시가 해당 응답을 재사용할 수 있습니다.
- 클라이언트(브라우저) 캐시에는 적용되지 않고, 공유 캐시에만 영향을 미칩니다.
stale-while-revalidate:- 이 디렉티브는 캐시된 응답이 만료된 경우에도, 새 응답을 가져오는 동안 만료된 캐시된 응답을 계속 사용할 수 있도록 합니다.
- 즉, 새로운 데이터를 가져오는 동안 사용자는 이전(만료된) 데이터를 계속 볼 수 있으며, 이로 인해 사용자 경험이 중단되지 않고, 새 데이터를 가져오는 백그라운드 작업이 완료된 후에만 업데이트된 내용이 반영됩니다.
-
이러한 캐시 정책으로 인해서 NextJS에서는 SSR과 자체 API를 제외하고는 캐시 정책을 개발자가 설정해줄 수 없다.