HTTP Cache - web.dev에 정리된 내용을 나에게 필요한 내용만 정리한 글이다. 번역기로 번역한 문장도 많아서 부정확할 수도 있다.
네트워크를 통해 무언가를 가져오는 작업은 느린 동시에 비용도 많이 든다. 크기가 큰 응답은 클라이언트와 서버 사이에 많은 왕복을 필요로 하므로, 응답을 사용할 수 있게 되어 브라우저가 처리할 수 있게 되는 시기가 지연되고 방문자에 대한 데이터 비용도 발생한다. 따라서 이전에 가져온 리소스를 캐시했다가 재활용할 수 있는 기능은 성능 최적화에 있어 중요한 측면이다.
모든 브라우저에 HTTP 캐시 구현이 포함되어 있다. 각 서버 응답이 올바른 HTTP 헤더 지시문을 제공하여 브라우저에 해당 브라우저가 응답을 캐시할 시점과 기간을 지시하는지 확인하기만 하면 된다.
브라우저 호환성
HTTP 캐시라는 단일 API는 없지만 아래의 API 모음의 일반적인 이름이 HTTP 캐시이다.
HTTP Cache 작동 방식
브라우저가 만드는 모든 HTTP 요청은 먼저 브라우저 캐시로 라우팅되어 요청을 수행하는 데 사용할 수있는 유효한 캐시 응답이 있는지 확인한다. 일치하는 항목이 있으면 캐시에서 응답을 읽어 전송으로 인해 발생하는 네트워크 대기 시간과 데이터 비용을 모두 제거한다.
Request Header : 추가 설정해줄 필요 없음
웹앱의 나가는 요청에 포함되어야하는 중요한 헤더가 많이 있지만 브라우저는 요청을 할 때 거의 항상 사용자를 대신하여 헤더를 설정한다. If-None-Match 및 If-Modified-Since와 같이 최신값 확인에 영향을 미치는 요청 헤더는 브라우저가 HTTP 캐시의 현재 값을 이해 한 경우에만 나타난다.
결론적으로 브라우저가 추가 노력없이 자동으로 HTTP 캐싱을 처리한다.
Response headers: configure your web server
HTTP 캐싱 설정에서 가장 중요한 부분은 웹 서버가 각 발신 response에 추가하는 header이다. 다음 헤더는 모두 효과적인 캐싱 동작에 영향을 준다.
- Cache-Control: 지시문을 반환하여 브라우저 및 기타 중간 캐시가 개별 응답을 캐시하는 방법과 기간을 지정할 수 있다.
- ETag: 브라우저가 만료 된 캐시 된 응답을 찾은 경우, 서버에 작은 토큰 (일반적으로 파일 내용의 해시)을 보내 파일이 변경되었는지 확인할 수 있다. 서버가 동일한 토큰을 반환하면 파일이 동일한 것이므로 다시 다운로드 할 필요가 없다.
- Last-Modified: ETag와 동일한 용도로 사용되지만 ETag의 콘텐츠 기반 전략과 달리 시간 기반 전략을 사용하여 리소스가 변경되었는지 확인한다.
Nginx를 구성하는 방법에 대한 지침
Cache-Control 응답 헤더를 그대로 두어도 HTTP 캐싱이 비활성화되지 않는다. 브라우저는 특정 유형의 콘텐츠에 가장 적합한 캐싱 동작 유형을 효과적으로 추측해서 실행한다. 제공하는 것보다 더 많은 제어를 원할 때는 시간을내어 응답 헤더를 구성해라.
Which response header values should you use?
- 버전이 지정된 URL에 대한 수명이 긴 캐싱: 버전이 지정된 URL은 캐시 된 응답을 더 쉽게 무효화 할 수 있기 때문에 좋은 방법입니다. 버전 관리 정보를 포함하고 내용이 변경되지 않는 URL에 대한 요청에 응답 할 때 Cache-Control : max-age = 31536000을 응답에 추가하십시오.
3153600초는 1년이다. RFC 2068 에서는 변경할 일이 없는 콘텐츠더라도 최대 1년의 캐시 수명을 설정하는 가이드라인이 있다.
- 버전이없는 URL에 대한 서버 재 검증: 모든 URL의 버전이 관리되는 것은 아니다. 그리고 모든 웹 애플리케이션에는 HTML 파일이 필요한데, HTML은 대부분 버전 관리를 지원하지 않는다.
HTTP 캐싱만으로는 네트워크를 완전히 피할 수 있을만큼 강력하지 않다. 그러나 네트워크 요청이 가능한 한 빠르고 효율적인지 확인하기 위해 취할 수있는 몇 가지 단계가 있다.
no-cache, no-store
- no-cache: 매 요청마다 ETag를 통해 자원의 유효성 확인. Cache-Control의 max-age가 0과 같음.
- no-store: 자원을 캐시하지 않음. 요청할 때마다 요청이 서버로 전송되고 전체 응답이 다운로드된다.
public, private
- public: 중간 단계를 포함해 캐시 가능하다. 대부분의 경우, 명시적 캐싱 정보(예: 'max-age')가 응답이 어떠한 경우든지 캐시가 가능하다고 나타내므로 'public'이 필요하지 않다.
- private: 중간 단계에 캐시를 하지 않는다. 즉, 사용자 브라우저는 캐시할 수 있지만 CDN은 캐시할 수 없다.
이와 함께 ETag 또는 Last-Modified, 두 개의 추가 응답 헤더 중 하나를 설정하는 것도 도움이 될 수 있다.
최초 요청시에 Response에 Cache-Control에 대한 값을 추가하면
두 번째 요청부터는 Request header에 if-none-match 값이 같이 온다.
if-none-match 값과 Etag 값이 일치하면 서버가 304 Not Modified HTTP 응답으로 응답 할 수 있다. 이는 "이미 가지고있는 것을 계속 사용하십시오!"와 동일하다. 이러한 유형의 응답을 보낼 때 전송할 데이터가 매우 적으므로 일반적으로 요청중인 실제 리소스의 복사본을 실제로 다시 보내는 것보다 훨씬 빠르다.
최적의 Cache-Control 정책 정의
Summary
HTTP 캐시는 불필요한 네트워크 요청을 줄이므로 로드 성능을 향상시키는 효과적인 방법이다. 모든 브라우저에서 지원되며 설정하는 데 많은 작업이 필요하지 않다.
- Cache-Control: no-cache: 매번 사용하기 전에 서버에서 재 검증해야하는 자원
- Cache-Control: no-store: 캐시되지 않아야하는 리소스
- Cache-Control: max-age=31536000: 버전이 지정된 리소스의 경우
또한 ETag 또는 Last-Modified 헤더를 사용하면 만료 된 캐시 리소스를보다 효율적으로 재 검증 할 수 있다.
서버에서 아무 설정도 해주지 않는다면 no-cache, no-store,max-age=0 으로 세팅이 되는 것 같다.
- https://stackoverflow.com/questions/21410317/using-gzip-compression-with-spring-boot-mvc-javaconfig-with-restful
- https://gunju-ko.github.io/spring/spring-boot/2018/06/16/SpringBootCompression.html
- https://code-masterjung.tistory.com/60
- https://www.w3schools.com/css/tryit.asp?filename=trycss_sprites_img
- http://jinolog.com/programming/2014/01/31/reducing-page-weight.html
'Etc.' 카테고리의 다른 글
Github API issue + JS로 댓글 기능 만들기 (0) | 2021.06.01 |
---|---|
API vs Library vs Framework (0) | 2021.01.12 |
HTTP (0) | 2020.09.24 |
TDD 정리 (0) | 2020.02.17 |
Git (0) | 2019.11.07 |