🍬

Web Cache(웹 캐시)


웹 캐시란 클라이언트가 요청하는 HTML, CSS, JavaScript, 이미지 등에 대해 복사본을 특정 위치에 저장해놓고, 동일한 리소스가 요청되면 복사본을 제공하는 기능이다. 서버를 통해 내려받는 리소스의 양이 적어지니 응답 시간이 감소하고 네트워크 트래픽도 줄일 수 있다.

웹 캐시는 크게 두 가지로 나눌 수 있다.

  • Private Cache: 클라이언트에 한정된 캐시로, 보통 크라우저 캐시를 지칭한다.
  • Shared Cache: 양 끝단(클라이언트와 서버)이 아닌 네트워크 상에서 제공되는 캐시다. 리버스 프록시나 CDN 등이 있다.

Browser Cache(Private Cache)

브라우저 또는 HTTP 요청을 하는 클라이언트의 내부 디스크나 메모리에 복사본을 저장해놓는다. 개인에 한정된 캐시로, 페이지 재방문이나 뒤로가기시 효율을 극대화시켜준다.

브라우저는 어떤 리소스를 캐시할지 HTTP 헤더를 사용해서 파악한다.

HTTP/1.0HTTP/1.1
요청응답요청응답
ValidationIf-Modified-SinceLast-ModifiedIf-None-MatchEtag(Entity tag)
FreshnessPragmaExpiresCache-ControlCache-Control

파일이 이전과 비교해서 변경됐는가를 체크하는 validation과, 캐시의 만료 여부를 체크하는 freshness로 구성된다. HTTP/1.0의 헤더의 HTTP/1.1의 헤더가 중복 선언되면 1.1에 정의된 헤더가 우선순위를 가진다.

Etag

Etag는 캐시가 유요한지 알려주는 토큰 역할을 하는 문자열이다. 보통 컨텐츠를 해싱한 값을 사용한다.

클라이언트가 첫 번째 요청에 대한 응답으로 Etag를 받은 후, 그 다음 요청부터는 If-None-Match 헤더의 값으로 Etag 값을 보내서 서버로부터 컨텐츠가 변경됐는지 확인받을 수 있다. 서버는 컨텐츠가 바뀌지 않았다면 304(not modified)로 응답하고 클라이언트는 캐시된 컨텐츠를 사용하게 된다.

Cache-Control

Cache-Control의 헤더 값으로 캐시의 생명 주기를 다룰 수 있다.

  • max-age=[sec]
    요청 시간으로부터 유효한 시간을 지정한다. 유효한 시간이 지나기 전이라면, 브라우저는 서버에 요청을 보내지 않고 디스크/메모리에서 캐시를 읽어와
  • no-cache
    캐시는 사용하지만, 사용하려고 할 때마다 서버에 재검증 요청을 보낸다. max-age=0,must-revalidate와 똑같이 동작한다. 캐시의 장점을 일정부분 취하면서 컨텐츠의 freshness를 강제로 유지하고 싶을 때 유용하다.
  • no-store
    캐시를 절대로 해서는 안되는 리소스일 때 사용한다. 브라우저는 어떤 경우에도 캐시 저장소에 해당 리소스를 저장하지 않는다.

Fingerprinted URLs

Webpack, Rollup 같은 번들러로 빌드를 하면 보통 번들된 파일을 해시하게 된다. 예를 들어, sitecode.af12de.js와 같은 형태의 번들된 파일이 나온다. 매 빌드마다 해시값이 달라지기 때문에 각 번들된 파일은 유일한 컨텐츠라고 생각할 수 있다.

이렇게 JS, CSS 파일을 관리했을 때, 같은 URL에 대해 내용이 바뀔 수 있는 경우는 없다. 내용이 바뀔 여지가 없으므로 리소스의 캐시가 만료될 일도 없다. 이런 파일들에 대해서는 클라이언트가 복사본을 영원히 가지게 할 수 있다.

1Cache-Control: max-age:31536000,immutable

굳이 해싱이 아니더라도 파일에 버전을 명시(app-v2.min.js)하거나 쿼리 스트링을 적용(app.min.js?version=2)하는 방법을 사용할 수 있다.

Shared Cache

CDN(Content Delivery Network) 같은 중간 서버를 사용하면 캐시는 여러 곳에 생길 수 있다. 현대적인 캐싱에 대한 기본값은 아무 캐싱을 하지 않고 CDN으로부터 컨텐츠를 가져오는 것이다. CDN는 유저와 네트워크 상에서 서버보다 가깝게 위치하기 때문에 빠르게 리소스를 전달해줄 수 있다.

CDN 같은 중간 서버가 특정 리소스를 캐시할 수 있는지, 언제까지 캐시해야하는지 Cache-Control 헤더로 알려줄 수 있다.

  • private
    Private cache, 즉, 브라우저만 캐시를 저장할 수 있음을 뜻한다.
  • public
    모든 사람과 중간 서버가 캐시를 저장할 수 있음을 뜻한다.
  • s-maxage
    중간 서버에만 적용되는 max-age를 설정할 수 있다.

참조