사전 브라우저 캐시
개념

브라우저 캐시

gabury1고친 사람 github-actions[bot]

브라우저 캐시는 한 번 받아 온 웹 파일을 브라우저가 보관해 두었다가 다음번에 다시 꺼내 쓰는 장치입니다. 같은 로고 이미지를 두 번째로 볼 때는 서버까지 다시 가지 않고 보관해 둔 복사본을 씁니다. 브라우저가 쓰는 다른 저장소를 캐시라 부르는 사람도 있습니다. 이 항목은 받아 온 응답을 다시 쓰는 캐시를 다룹니다.

쉽고 빠른 이해

브라우저 캐시는 받아 온 파일을 브라우저가 보관해 두고 다시 쓰는 저장소입니다. 사이트 로고처럼 페이지마다 똑같이 나오는 파일이 여기 들어갑니다.

이것이 없으면 브라우저는 페이지를 열 때마다 모든 파일을 처음부터 다시 받습니다. 뒤로 가기를 눌러 방금 본 페이지로 돌아가는 것도 새로 내려받는 일이 됩니다.

도는 모양은 셋입니다.

  1. 서버가 응답을 보내면서 언제까지 다시 써도 되는지를 함께 알려 줍니다
  2. 브라우저는 응답과 그 기한을 함께 보관합니다
  3. 같은 파일이 다시 필요하면 기한을 봅니다. 아직 남았으면 서버에 안 가고 보관한 것을 씁니다

대가가 있습니다. 서버에서 파일을 고쳐도 기한이 남아 있는 동안에는 옛 파일이 보입니다.

상세

자주 쓰는 서류를 매번 문서고까지 가서 뽑아 오지 않고 책상 서랍에 한 부 넣어 둡니다. 서랍을 열면 걸어갈 일이 없으니 바로 꺼내 씁니다.

HTTP(HyperText Transfer Protocol)는 브라우저가 서버에서 파일을 받아 올 때 쓰는 규칙입니다. 브라우저 캐시는 이 규칙으로 받아 온 응답을 브라우저가 자기 컴퓨터에 저장해 두고, 같은 응답이 다시 필요할 때 서버에 안 가고 꺼내 쓰는 저장소입니다. 브라우저는 저장해 둔 복사본만 봐서는 서버의 원본이 그 사이에 고쳐졌는지 알 수 없습니다.

무엇이 들어가는지는 사이트를 열어 보면 짐작이 갑니다. 로고 그림, 화면 꾸밈을 적은 스타일 파일, 글꼴 파일처럼 페이지마다 똑같이 나오는 것이 대부분입니다.

이것이 없으면 브라우저는 페이지를 열 때마다 모든 파일을 처음부터 다시 받습니다. 받아 오는 동안 화면은 비어 있고, 서버는 같은 파일을 접속한 사람 수만큼 되풀이해 내보냅니다.

두 번째 요청이 흐르는 길

이 소절은 브라우저가 이미 받아 둔 파일을 다시 필요로 할 때 무엇을 보고 무엇을 정하는지 봅니다. 보는 것은 보관함과 기한 둘입니다.

flowchart TD
    A["파일이 필요하다"] --> B{"보관해 둔 복사본이 있나"}
    B -->|없다| S["서버에서 받아 온다"]
    B -->|있다| C{"기한이 아직 남았나"}
    C -->|남았다| D["보관한 것을 꺼내 쓴다"]
    C -->|지났다| E["서버에 바뀌었는지만 묻는다"]
    E --> F{"바뀌었나"}
    F -->|안 바뀌었다| D
    F -->|바뀌었다| S

갈림이 둘입니다. 복사본이 있느냐, 그리고 그 복사본을 더 물어보지 않고 써도 되느냐입니다.

첫 갈림에서 복사본이 없다고 나오는 것을 캐시 미스라고 부릅니다. 이때는 서버까지 가서 파일을 통째로 받아 오고, 받은 김에 보관도 해 둡니다. 다음 요청은 둘째 갈림으로 들어옵니다.

언제까지 써도 되는지 정하는 쪽

복사본을 얼마나 오래 써도 되는지는 브라우저가 스스로 정하지 않습니다. 응답을 보낸 서버가 정해서 알려 줍니다. 파일이 얼마나 자주 바뀌는지는 서버 쪽만 알기 때문입니다.

알려 주는 수단은 헤더입니다. 헤더는 응답 본문과 따로 붙는 이름표 줄입니다. 그중 한 줄이 이 응답을 얼마 동안 다시 써도 되는지를 적습니다.

Cache-Control: max-age=600   // 600초 동안 안 물어도 됨

같은 헤더로 보관하지 말라고 적을 수도 있습니다. 사람마다 내용이 다르거나 한 번 낡으면 바로 곤란해지는 응답이 그렇습니다. 장바구니 화면과 계좌 잔액이 그런 응답입니다. 반대로 고쳐질 일이 거의 없는 로고나 글꼴에는 긴 기한을 답니다.

복사본을 만든 뒤로 흐른 시간을 나이라고 부릅니다. 다시 묻기 전까지 써도 된다고 정해 둔 길이는 신선도 수명이라고 부릅니다. 나이가 신선도 수명을 아직 안 넘었으면 그 복사본은 신선합니다. 이 판정에 붙은 이름이 신선도입니다.

기한이 지난 복사본을 곧바로 버리지 않는 까닭

기한이 지났다는 것은 파일이 바뀌었다는 뜻이 아닙니다. 다시 물어볼 때가 됐다는 뜻입니다. 그동안 아무것도 안 바뀌었을 수 있고, 그렇다면 같은 파일을 다시 받는 것은 낭비입니다.

그래서 브라우저는 보관하던 복사본의 딱지를 들고 서버에 묻습니다. 서버가 응답마다 붙여 주는 이 딱지를 ETag라고 부릅니다. 파일 내용이 바뀌면 딱지도 바뀝니다.

If-None-Match: "v3-logo"     // 이 딱지 그대로냐
304 Not Modified             // 그대로다. 본문 없음

딱지가 같으면 서버는 본문을 안 보내고 바뀐 것이 없다는 답만 보냅니다. 브라우저는 보관하던 복사본을 계속 씁니다. 이렇게 묻고 확인하는 일을 검증이라고 부릅니다.

남과 나눠 쓰지 않는 캐시

브라우저 캐시는 그 브라우저를 쓰는 한 사람만의 보관함입니다. 이렇게 한 사람 몫만 담는 캐시를 사설 캐시라고 부릅니다.

같은 응답을 대신 보관해 주는 곳이 브라우저와 서버 사이에도 있습니다. 요청을 받아 서버에 넘기고 답을 돌려주는 중계자를 프록시라고 부르고, 이런 중계자를 여러 지역에 깔아 둔 것을 CDN(Content Delivery Network)이라고 부릅니다. 둘은 여러 사람의 요청을 한데서 받으므로 보관한 응답도 여럿이 나눠 씁니다. 이런 캐시를 공유 캐시라고 부릅니다.

둘의 차이는 로그인한 사람의 이름이 박힌 페이지에서 드러납니다. 사설 캐시는 그 응답을 그 사람에게만 다시 내주므로 저장해도 됩니다. 공유 캐시가 같은 응답을 저장하면 다음 사람에게 남의 화면을 내주게 됩니다. 그래서 서버는 어느 쪽까지 저장해도 되는지를 응답마다 갈라 적어 보냅니다.

고친 파일을 보여 주려면

대가는 기한을 정하는 쪽에서 나옵니다. 기한을 길게 잡을수록 서버에 덜 가지만, 파일을 고쳐도 기한이 끝날 때까지는 옛 파일이 보입니다. 브라우저 안의 보관함은 서버가 지울 수 없습니다.

그래서 널리 쓰는 수법은 파일 이름 자체를 바꾸는 것입니다. 내용이 바뀌면 이름도 바뀌게 만들어 두면 브라우저에게는 처음 보는 파일이 되고, 그 파일은 보관함에 없으므로 새로 받아 옵니다.

logo.a1b2c3.png   // 내용이 바뀌면 이름도 바뀐다

옛 이름의 복사본은 아무도 안 부르게 되어 보관함에 남아 있어도 해가 없습니다. 이 수법을 캐시 버스팅이라고 부릅니다.

보관함 크기에도 끝이 있습니다. 브라우저는 정해 둔 크기를 넘으면 오래 안 쓴 것부터 밀어냅니다. 기한이 넉넉히 남은 복사본이라도 이미 밀려나 없을 수 있다는 뜻입니다.

관련 항목

브라우저 캐시가 신선한지 재는 잣대

신선도 · 나이 · 신선도 수명 · 만료 시각 · 검증 · 캐시 키

서버가 브라우저 캐시를 조종할 때 쓰는 헤더 필드

Cache-Control · ETag · Last-Modified · Expires · Vary · If-None-Match · If-Modified-Since

브라우저 캐시의 동작을 정의하는 표준 문서

RFC 9111 · HTTP · HTTP 캐시 · stale-while-revalidate

브라우저 캐시가 속하는 상위 분류

캐싱 · 캐시 · 사설 캐시 · 클라이언트 사이드 캐싱

같은 응답을 대신 보관하는 다른 캐시

공유 캐시 · 프록시 캐시 · 리버스 프록시 캐시 · CDN

브라우저 캐시 말고 브라우저가 따로 두는 저장소

쿠키 · localStorage · 세션 스토리지 · IndexedDB · 서비스 워커 · 뒤로 가기 캐시

브라우저 캐시 요청이 거치는 참여자

브라우저 · 오리진 서버 · 프록시 · 리버스 프록시 · 웹 서버

브라우저 캐시에서 자주 나는 문제

캐시 미스 · 낡은 데이터 · 캐시 무효화 · 캐시 버스팅 · 캐시 스탬피드

다른 층위에서 같은 이름을 쓰는 캐시

CPU 캐시 · 페이지 캐시 · DNS 캐시 · 버퍼 풀

다른 이름: browser cache · 브라우저 캐싱 · 웹 브라우저 캐시