일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- hokidoki
- queue
- 리액트 예제
- hokeys
- HTML
- 힛잇
- data structure
- 비동기
- 호키도키
- TDD
- react
- javascript
- Svelte
- 호키스
- 계명대
- 개발자
- 계명대 이종호
- 자스민
- 자바스크립트
- jest
- 스위프트
- SWIFT
- 개발
- IOS
- 자료구조
- 스벨트
- Hitit
- 자바스크립트 자료구조
- 리액트
- 이종호
- Today
- Total
Dog foot print
WEB CACHE 본문
WEB CACHE
서론
Validation 서버에 새로운 버전의 프로덕트를 올릴 때 가끔 브라우저 캐싱때문에, 캐시된 데이터를 삭제하거나, 시크릿 모드에서 확인을 하였다. 이를 해결하기 위해서, 번들링 할때 JS파일 이름에 해싱데이터를 넣어 새로운 JS파일을 업로드 하게하고, HTML파일에 메타태그를 추가함으로써, HTML파일을 캐싱되지 않게 하였다. 캐싱에 대해서는 간단하게는 알고 있었지만, 오늘 만큼 공부해본적은 없었기에 이에 대한 기록을 남겨보도록 한다.
캐싱이란 ?
Caching (캐싱)이란 어떤 데이터가 연산되어 산출 되었거나, 외부 저장소에서 로드 되었을 때 이에 대해 특정 저장소(Register, L!,L2,L3)에 저장하여, 빠르게 다시 사용 할 수 있게 하는 방법이다.
캐쉬를 사용하게 된다면, 하드디스크에 존재하는 파일을 메모리에 불러오는 시간을 단축하거나, 요청에 대한 저장된 응답을 줌으로써 요청하는 자와 응답하는 자 모두 좋은 성능을 가질 수 있다.
웹 캐싱이란 ?
Web caching(웹 캐싱)이란? 브라우저에서 사용자의 요청으로 받은 리소스 (HTML,CSS,JS,JPG 등)를 저장소에 보관하다, 사용자가 동일한 요청을 하였을 때 이 저장소에 있는 사본을 클라이언트에게 전달 함으로써 Responser
, Requester
모두 성능 향상을 이루어 낼 수 있는 방법이다.
웹 캐싱 플로우
만약 브라우저가 어떤 요청을 서버로 전달 하게 되면 브라우저는 먼저, 해당 리소스가 저장소에 존재하는지 찾아 본다. 만약 저장소에 리소스가 존재하지 않는다면, 다시 한번 서버로 요청을 보내게 된다. 이후, 브라우저는 이 응답에 대한 결과를 브라우저 저장소에 저장하게 된다.
만약 다시 요청 하였을 때 브라우저는 다시 한번 저장소를 확인하게 된다. 이후, 저장소에서 해당 리소스가 존재하는 경우, 이 리소스를 전달하게 되는 것으로 요청과 응답이 종료된다.
위와 개념이 매우 비슷한 프록시 캐싱 기법이라는 것이 존재한다. 이 프록시 캐싱은 브라우저 캐싱과 다르게, 사용자와 저장소가 1:1 이 아닌 1:M 저장소이다.
프록시 캐싱은 서버를 운용하는 회사에서 설치한 사설 저장소이다. 즉 브라우저 저장소와 달리, 특정 서버로 전달되는 요청에 대한 리소스만 저장하게 된다. 프록시 저장소의 관계는 1:M 이지만 특정 유저에게 전달하는 요청에 대해서 리소스를 보관하는 역할을 하기에 리소스와 유저간의 관계는 1:1이다.
HTTP Cache-Control header
모든 리소스들은 HTTP 요청에 의해서 클라이언트로 가져오게 되고, 저장소에 캐싱되게 된다. 그러나 다음과 같이 만약 리소스가 업데이트 되었는데, 캐싱 되어 있는 리소스는 구 버전인 경우가 존재하여 사용자가 사용하는 리소스는 구 버전 일 수 있다.
이런 경우에는 리소스 관리자와 클라이언트 입장에서는 좋지 못한 경험일 것이다. 관리자가 직접 연락하여, “캐싱으로 발생된 문제입니다. 캐싱을 초기화 해주세요.”하고 말 할 수도 없는 노릇이니 말이다. 그래서 응답을 하는 서버는 리소스에 대한 응답의 헤더에 이 리소스에 대한 캐싱 설정들을 하여, 리소스의 캐싱을 관리 할 수 있다.
Cache-Control헤더는 Multi-value를 사용 할 수 있는 헤더로써, 아래에 나오는 다양한 값들을 조합하여 사용 할 수 있다.
no-store
요청과 응답의 리소스에 대해서 어떤 것도, 저장하지 않고 매번 서버로부터 다운로드 하게 된다. (캐싱 문제에 대해서는 완벽히 해결되는 값이지만 트래픽 이슈가 발생한다.)
no-cache
캐싱된 데이터를 사용하지만, 이 리소스가 사용해도 되는 리소스인지 서버로 확인을 받고 사용한다.
public | private
public
은 어떤 응답 이더라도, 캐시 되어도 괜찮다는 의미이다. 반대로 private
는 공유 캐시에 의해 저장되어서는 안된다.
max-age
Max-age=<second>
형태로 사용되는 max-age는 이 캐시된 리소스가 유효한 시간을 의미한다. 이 값의 second
는 ms
가 아니며, 응답 받은 시간 이후 만료되는 시간을 의미한다.
must-revalidate
이값은 해당 캐시가 오래된 리소스인 경우, 그 상태를 서버로 부터 확인을 받아 사용하는지 검증
의 의미를 담는 값이다.
Expires
Note : 이 헤더의 첫 글자는 대문자가 맞다.
이 헤더는 GMT 시간을 값으로, 리소스가 유효한 시간을 명시해주는데, 만약 max-age
값이 존재한다면, Expires는 무시된다.
캐쉬는 영원히 사용 되는가 ?
이론적으로는 영원히 캐싱된 리소스를 사용 할 수 있다. 그러나, 캐싱되는 저장소 또한 유한한 저장 공간을 가졌기 때문에, 주기적으로 제거된다. 이를 캐시 축출
이라고 부른다. 브라우저 캐시 저장소와 달리 프록시 캐시 저장소는 주기적으로 갱신되어야 하는 로직이 필요로 하다.
만약 위와 같이 유효기간이 만료된 캐싱 리소스가 존재 할 때, 클라이언트가 해당 리소스를 요청하게 되면 어떻게 될까 ?
리소스에는 해싱되어 있는 e-tag-value
라는 것이 존재한다. 만약 만료된 캐싱 리소스를 요청하게 되면, 스토리지는 이 e-tag-value
를 if-non-match
헤더에 담아, 서버에게 이 리소스를 요청한다. 그럼 서버는 만약 해당 e-tag-value
가 유효한 값이라면, body에 리소스를 담지 않고, 304
코드와 not-modified
헤더를 담아, 저장소에게 응답한다. 그럼 저장소는 응답에 따라, 만료된 리소스를 그대로 클라이언트에게 전달한다.
만료기간이 명시되지 않은 캐시
만약 max-age
헤더나, Expires
헤더가 존재하지 않는 경우에는 Last-modified
헤더를 찾는다. 이 헤더는 캐시 컨트롤에 직접적으로 사용 되는 헤더가 아니라, 해당 리소스가 언제 마지막으로 수정 되었는지에 대한 GMT 시간을 값으로 가지고 있다. 브라우저는 이 헤더의 GMT시간에서 Date
값을 빼고 10으로 나눈 결과가 이 리소스의 유효한 시간으로 판단한다.
expirationTime = responseTime + freshnessLifetime - currentAge
Note : 이 헤더는 직접적인 캐시에 대한 유효 시간을 판단하기 위한 헤더가 아니므로, Max-age
에 비해 비교적 덜 정확하다.
어떤 캐싱 헤더 전략을 사용해야 할까 ?
모든 리소스에 대하여, 완벽한 유효기간을 예상하는 것은 거의 불가능하다. 그렇기에 리소스별로 적절한 시기를 예상하는 것이 중요하다. 만약 너무 오랜 기간의 캐싱 유효기간을 설정해버리면, URL이 변경되거나 강제로 캐시를 삭제하지 않는 이상 영원히 해당 파일을 사용해야 한다. 만약 주기가 작다면 서버 재검증으로 인하여, 오버헤드가 발생 할 것이다.
컨텐츠 , 아티클
아티클과 같은 성격의 게시물은 긴 시간동안 캐싱되어서는 안된다. 수정 될 여지가 매우 높기 때문이다. 그렇지만 no-cache
,no-store
값을 같이 사용해서, 캐싱을 막기에는 컨텐츠의 크기가 큰 경우, 오버 헤드가 발생할 가능성이 있다. 그렇기에 비교적 적은 시간을 활용하여, 서버로부터 재검증을 통해 컨텐츠의 신선도를 파악하는 것이 좋다.
변경 가능성이 적은 CSS 와 JS
변경 가능성이 적은 리소스라 함은, 브라우저의 기본 CSS속성을 초기화 해주는 reset-css
파일이나, 문서 전체에서 color
,value
를 담고 있는 CSS 들을 말한다. 이러한 것들은 변경될 여지가 매우 적기 때문에, 가장 긴 시간의 max-age
값을 가지는 것이 효율적인 전략이다. 그러나, 이 경우에서 리소스가 변경 되었다면, 고객에게 캐시를 삭제해달라는 요청을 하기 전까지는 오래된 파일을 사용하게 될 것이다.
위와 같은 문제를 해결하기 위해서 URL의 버저닝을 명시함에 따라, 파일을 새롭게 요청 할 수 있는 방법이 존재한다.
<script src="hokidoki.com/script?v=1"></>
//변경 시 새로운 리소스를 요청
<script src="hokidoki.com/script?v=2"></>
(만약 이런 방법까지 사용하지 않고, 최대 시간을 지정 해버린 경우 대참사가 발생할 수도 있다.)
변경 가능성이 높은 CSS와 JS
변경 가능성이 높은 리소스는 SPA에서 메인으로 사용되는 script 파일이나, 컴포넌트의 스타일을 담고 있는 css 파일들을 일 컷는다. 이러한 파일들은 버그 수정, 새로운 기능의 추가로 배포되거나, Hot fix가 이루어져 빠른 생명주기를 가지게 된다. 만약 이런 리소스에 매우 긴 시간의 캐싱헤더를 가지게 되면, 새로운 사용자와 기존 사용자가 사용하는 문서의 기능과 문제가 다를 수 있다. 그렇기에 이런 리소스는 no-cache
헤더와E-tag
를 통하여,주기적으로 서버로부터 재검증을 받아 신|구 사용자간의 기능 격차를 줄여야 한다.
'기술' 카테고리의 다른 글
통신 속도 향상을 위한 노력 (DNS편) (0) | 2022.07.01 |
---|---|
통신 속도 향상을 위한 노력 (기본 지식편) (0) | 2022.06.01 |
Under 1px line (0) | 2021.06.07 |