캐싱의 기본 개념
caching 은 어플리케이션의 처리 속도를 높여주는 효율적인 아키텍처 패턴이다.
대부분의 프로프램은 동일한 데이터에 대한 엑세스가 반복되기 때문에, 이미 가져온 데이터나 계산된 값의 복사본을 저장함으로써 처리속도를 향상시킬 수 있다.
웹 캐시(Web Cache)
클라이언트가 웹 사이트에 접속 할때 정적인 컨텐츠들을 특정위치에 저장하여, 서버에서 컨텐츠를 매번 요청하는 것이 아니라,
저장되어있는 특정 위치에서 불러옴으로써 응답시간을 줄이고, 서버의 부하를 감소시킬 수 있다.
*정적 컨텐츠 : HTML, CSS, JS, 이미지, 동영상 등
*캐시 저장 위치 : client, network 등
웹 캐시의 종류
1. Browser Caches
- 클라이언트(브라우저)의 내부 디스크에 저장
- 개인에 한정된 캐시
2. Proxy Caches
- 네트워크 상에 저장(클라이언트x, 서버x)
- 한정된 수의 클라이언트를 위하여, 무한대의 웹 서버 컨텐츠를 캐시
3. Gateway Caches(Reverse Caches or Surrogate Propxy Caches) : CDN
- 서버 앞단에 설치되어 요청에 대한 캐시
- 요청에 대한 효율적인 분배, 로드밸런싱, SSL, 정적 컨텐츠 제공
- 무한대의 클라이언트에게 한정된 수의 웹 서버 컨텐츠를 제공
캐시 컨트롤
브라우저는 한번 요청한 파일은 이후 부터 캐시를 사용하는데,
만약 캐시되면 안되거나, 캐시된 내용에 변경이 발생할 수 있기 때문에 캐시를 컨트롤 하는 방법이 필요합니다.
아래 헤더 프로퍼티들이 그런 역할을 해줍니다.
* status가 304 라면 캐시에서 컨텐츠를 로드합니다.
* SSL Cache-Control에서 기본적으로 private 속성을 가지기 때문에 은 캐시되지 않습니다. (Cache-Control에서 public 으로 명시하면 캐시할 수 있다)
* Authorization 헤더가 들어간 요청또한 캐시되지 않습니다.
* 모든 요청은 freshness 에 대한 validation 체크가 필요하기 때문에, header와 cookie 등에 대한 데이터전송 1kb가 항상 발생합니다.
HTTP headers
1. Etag (Entity Tag)
- 브라우저는 최초 응답시 받은 etag값을 요청 헤더에 항상 if-None-Match 프로퍼티에 넣어 요청파일의 Etag와 비교하여 동일하다면 캐시에서 컨텐츠를 가져온다.
- Etag 는 서버마다 생성하는 값이 다르고, 파일마다 고유한 값을 가집니다.
- 파일이 수정되면 Etag 도 바뀝니다.( Etag = Mtime + 알파로 해싱한 값)
- Etag 가 서로 동일하다면 304, 아니라면 200 을 반환한다.
2. Cache-Control
- 단일 값이 아닌, 여러값을 포함할 수 있습니다.
- max-age=초 : 요청한 시간으로부터 상대적인 시간을 나타냄, 몇초간 캐시할 것이냐 .. 등등
3. Last-Modified
- 정적 컨텐츠, html, css, js, 이미지 들의 마지막 수정된 날짜입니다. 이것으로 Etag 에 영향을 줍니다.
- Last-Modified 프로퍼티를 통해 수정됬음을 감지하한다
중간정리
1.브라우저의 모든 요청은 브라우저 캐시로 라우팅되어 유효한 캐시가 있는지 확인하고 있다면 캐시로부터 응답한다.
2.캐시유효기간이 지난 요청의 헤더에는 If-None-Match ,If-Modified-Since 가 포함된다.
3.응답의 Cache-Control 헤더를 통해서 방법과 기간을 지정할 수 있다.
4.만료된 캐시 응답이 있다면 Etag를 요청헤더에 포함하여, 서버가 동일한 Etag를 반환하는지 확인하고, 같을경우 다시 다운받지 않는다.
5.Last-Modified 는 수정된 날짜를 통해서 리소스가 변경되었는지 구분한다. (Etag 의 대체재격이라고 한다)
6.응답 헤더에 Cache-Control을 생략해도, 브라우저가 자동으로 추측하여 적합한 캐싱전략을 수행한다. 하지만 웹 서버별 적절한 헤더구성을 해주는 것이 좋다(nginx, apache ...)
버전이 있는 URL에 대한 캐싱
1년 캐싱하겠다는 소리인데..
보통은 버저닝이 된 리소스에 대해서 적용합니다.
Cache-Control: max-age=31536000
예를들면 /api/v1/home 은 v1 으로 버저닝이 되어있기 때문에 의미상 v1/home 이 쓰이지 않을 경우는 v2/home 이 될것입니다.
이 경우에는 두가지 리소스가 구분되기 때문에 가능한 전략입니다.
버전이 없는 URL에 대한 캐싱
이런 경우에는 Cache-Control 헤더가 미세하게 조정하는데 도움이 됩니다.
- no-cache : 캐시된 것을 사용하기 전에 서버에서 유효성검사를 반드시 한다.
- no-store : 브라우저와 다른 중간캐시(CDN) 가 어떤 것도 캐시하지 않는다.
- private : 브라우저는 파일을 캐시할 수 있지만, 중간캐시(CDN)은 캐시할 수 없다.
- public : 응답은 모든 캐시에 의해 저장될 수 있다.
* private 은 CDN, 브라우저자체 가능, public 은 브라우저만 가능 (개인캐싱과 공공캐싱)
최종정리
1. 브라우저는 자동으로 캐싱을 한다. Etag와 Last-Modified 값을 비교해, 서버 자원과 최초 요청해서 저장해놓은 자원을 비교하고, 다르면 다시 다운하고 아니면 저장된 값을 사용한다.
2.캐시가 있으면(max-age가 유효하면) 요청 자체를 하지 않고, 브라우저의 cache storage에서 데이터를 가져온다.
3. private은 CDN의 캐싱을 막고, 브라우저의 캐싱만을 허용한다. public 은 모두 허용한다.
4. status 코드가 304일 경우, 서버에다가 리소스에 대한 validation 체크는 하지만 데이터는 cache storage 에서 가져온다. (하지만 이를 반드시 보장하진 않는다)
'FE > browser' 카테고리의 다른 글
[Browser] Service Worker 로 push notification 구현하기 (0) | 2023.09.21 |
---|---|
[Browser] Web Worker 와 Service Worker (0) | 2023.09.20 |
[Broswer] EventTarget 과 Event, CustomEvent (0) | 2023.09.20 |
[Browser] window.addEventListener (0) | 2023.09.20 |
Browser 에서 얻을 수 있는 모든 길이와 좌표 그리고 스크롤 (0) | 2023.05.09 |