여러분, 브라우저에서 서버에 어떤 요청을 보냈을 때 [개발자 도구 -> Network 탭 -> Size 필드]에서 (memory cache) 또는 (disk cache)가 찍히는 걸 본 적이 있으신가요? 혹시 한 번도 본 적이 없으시다면, 지금 한 번 https://www.google.com 에 접속해서 [개발자 도구 -> Network 탭 -> Size 필드]에서 (memory cache) 또는 (disk cache)가 찍히는 걸 확인해 보세요! (보이지 않는다면 새로고침을 한 번 해주세요.)
(memory cache) 또는 (disk cache)가 찍혔다는 건 서버에 요청을 보내서 서버에서 데이터를 가져온 게 아니라, 브라우저의 memory 또는 브라우저에 접속한 host의 disk에서 캐싱된 데이터를 가져왔다는 뜻입니다.
그렇다면 이러한 브라우저의 캐싱은 누가 어떻게 제어하는 걸까요? 바로 서버가 HTTP 응답 헤더의 Cache-Control 속성을 통해 제어합니다.
예를 들어 Express.js 서버에서 아래와 같이 Cache-Control 속성에 max-age={seconds}라는 지시어를 넣어서 응답 데이터를 캐싱할 수 있어요.
const app = express();
app.get('/api/endpoint', (_, res) => {
res.set('Cache-Control', 'max-age=3600');
res.status(200).json({ message: 'success' });
});
여기서 max-age=3600은 무엇을 의미할까요?
"일단, 3600초만큼 데이터를 캐싱해두겠다"라는 말입니다. 제가 여기서 일단이라고 한 이유는 3600초가 지났을 때 곧바로 캐싱된 데이터가 사라지는 건 아니기 때문인데요, 이는 3600초가 지난 뒤 진행되는 재검증 요청과 관련이 있습니다. 재검증은 서버 측에서 해당 데이터를 그대로 사용해도 되는지 확인하는 작업을 말하는데요, 3600초가 지나면 서버로 재검증 요청을 보낸 뒤 사용해도 된다는 응답이 오면 그때 다시 캐싱된 데이터를 사용할 수 있게 됩니다. 다시 말해, 계속해서 재검증을 해도 데이터가 변경되지 않는다면 캐싱된 데이터는 끝까지 사라지지 않는다는 거예요.
위 내용이 조금 복잡하다면, 당장은 그냥 "Cache-Control 속성에 max-age={seconds}라는 지시어를 넣으면 {seconds}초만큼 데이터가 캐싱된다" 정도로만 이해하셔도 무방할 것 같습니다.
위의 예시로는 Cache-Control 속성에 max-age={seconds} 지시어만을 사용했지만, 그 외에도 아래와 같은 다양한 지시어들이 있습니다.
no-store: 데이터를 캐싱하지 않음
no-cache: 데이터를 캐싱하긴 하지만, 매 요청마다 서버 측에서 유효성 검사를 해야 함
max-age={seconds}: {seconds} 동안은 캐싱된 데이터를 사용하며, {seconds}가 지나면 서버 측에서 유효성 검사를 해야 함
public: 브라우저, 프록시 서버 등 어디에서든 데이터를 캐싱 가능
private: 브라우저에서만 데이터를 캐싱 가능
s-maxage={seconds}: 프록시 서버 등 중간 서버에서만 적용되는 속성으로 {seconds} 동안은 캐싱된 데이터를 사용하며, {seconds}가 지나면 서버 측에서 유효성 검사를 해야 함
TL;DR: 브라우저의 캐싱은 서버가 HTTP 응답 헤더의 Cache-Control 속성을 통해 제어합니다.
관련 내용은 https://github.com/sekhyuni/frontend-basic-concept/blob/main/browser/README.md#cache 에 조금 더 자세히 설명해두었으니, 참고하실 분들은 참고 부탁드립니다! :D
다음 내용이 궁금하다면?
이미 회원이신가요?
2023년 12월 25일 오전 9:20
좋은 글 감사합니다