[HTTP] 캐시기본동작 및 조건부 요청
✔ HTTP Header 캐시
캐시가 없는 경우(요청 예시)
#요청
GET /star.jpg
#응답
HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Length: 34012
lkj123kjddhdudieidjskskdhdjd987snshsjdksjdjskdjakasks
skskdjdjsjkdkd938372sksksks;oisjsjdkds;skskdl;
- GET 요청을 통해 star.jpg 이미지 요청
- 서버는 GET 요청에 맞는 이미지를 내려준다
- 이때 헤더와 바디의 용량은 아래와 같다
- HTTP 헤더: 0.1M
- HTTP 바디: 1.0M
캐시를 사용하지 않는다면?
- 서버는 헤더와 바디를 매번 생성하여 클라이언트에 전달을 해야한다
- 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운 받아야 한다
- 인터넷 네트워크는 H/D나 PC의 Memory보다 상대적으로 매우 느리고 비싸다
- 위 같은 이유로 브라우저 로딩 속도가 느려지기에, 사용자는 느린 속도를 체감
캐시 적용(요청 예시)
#요청
GET /star.jpg
#응답
HTTP/1.1 200 OK
Content-Type: image/jpeg
cache-control: max-age=60
Content-Length: 34012
lkj123kjddhdudieidjskskdhdjd987snshsjdksjdjskdjakasks
skskdjdjsjkdkd938372sksksks;oisjsjdkds;skskdl;
- cache-control: max-age=60
- 서버가 캐시의 시간을 지정하여 브라우저에 내려준다
- 해당 브라우저는 Storage 영역에 해당 내용을 저장한다
- 클라이언트에서 같은 요청을 할 경우 먼저 캐시를 뒤진 후 요청을 보낸다
캐시를 사용한다면?
- 캐시 가능 시간동안 네트워크를 사용하지 않아도 된다
- 비싼 네트워크 사용량을 줄일 수 있다
- 브라우저 로딩 속도 증가
- 빠른 사용자의 경험
캐시 시간이 초과된 경우?
- 캐시 유효 시간이 만료되면, 서버를 통해 다시 데이터를 조회하고 캐시를 갱신한다
- 이때 다시 네트워크 다운로드가 발생한다
- 클라이언트 캐시 유효 시간이 만료되었지만, 클라와 서버의 이미지가 똑같은 상황?
- 1M나 되는 이미지를 다시 다운로드 받을 필요가 있는가?
- 이 때 사용 되는 것이 조건부 요청
검증 헤더와 조건부 요청 I
I 캐시 시간 초과
캐시 유효 시간이 초과해서 클라에서 서버에 다시 요청하면 다음 두 가지 상황이 나타난다.
- 서버에서 기존 데이터를 변경함 ⭐️ => 🌟
- 서버에서 기존 데이터를 변경하지 않음 ⭐️
- 똑같은 이미지를 처음부터 끝까지 다운 받아야함
II 캐시 시간 초과
- 캐시 만료후 클라에서 서버로 요청을 보냈지만 서버에서 데이터를 변경하지 않음
- 데이터를 전송하는 대신에 저장해 두었던 캐시를 재사용 할 수 있다
- 단, 클라의 데이터와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법 필요
검증 헤더 추가 (첫번째 요청)
#요청
GET /star.jpg
#응답
HTTP/1.1 200 OK
Content-Type: image/jpeg
cache-control: max-age=60
Last-ModifiedL 2021년 08월 08일 14:28:00
Content-Length: 34012
lkj123kjddhdudieidjskskdhdjd987snshsjdksjdjskdjakasks
skskdjdjsjkdkd938372sksksks;oisjsjdkds;skskdl;
- Last-Modified
- 서버에서 최종 수정일을 넣어 브라우저에 전달
- 브라우저는 해당 내용을 로컬에 저장해둔다
클라이언트에서 서버에 재요청
GET /star.jpg
if-modified-since: 2021년 08월 08일 14:28:00
- 웹 브라우저가 서버에 요청을 보낼 때 if-modified-since Header를 붙여 전송
- 서버에서는 해당 이미지의 최종 수정일과 브라우저에서 보낸 날짜를 비교하여 판단
이미지 수정이 안되경우
HTTP/1.1 304 Not Modified
Content-Type: image/jpeg
cache-control: max-age=60
Last-Modified: 2021년 08월 08일 14:28:00
Content-Length: 34012
- 304 Not Modified
- 서버에서 날짜를 비교한 후 변경 내역이 없는 경우 위 같은 응답 반환
- HTTP Body 전송 x, 0.1M(Header)만 정송
- 캐시 만료 시간이 유효하다면 브라우저 내에서 캐싱을 하여 이미지를 뿌린다
검증 헤더와 조건부 요청 정리
- 캐시 유효 시간이 초과해도, 서버의 데이터가 갱신되지 않는다면
- 서버는 304 Not Modified + Header 메타 정보만 응답(바디 x) 반환
- 클라는 서버가 보낸 응답 헤더 정보로 캐시의 메타 정보 갱신
- 클라는 캐시 데이터 재활용
- 결과적으로 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드 하므로 실용적인 해결책
브라우저 캐싱 예시
- 위 이미지를 보면 로컬 브라우저의 캐시에서 가져온 것을 확인할 수 있다
검증 헤더와 조건부 요청 II
검증 헤더와 조건부 요청
- 검증 헤더
- 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
- Last-Modified, ETag
- 조건부 요청 헤더
- 검증 헤더로 조건에 따른 분기
- if-Modified-Since: Last-Modified 사용
- if-None-Match: ETag 사용
- 조건이 만족하면 200 OK
- 조건 만족하지 않으면 304 Not Modified
검증 헤더와 조건부 요청 예시
- if-Modified-Since: 이후에 데이터가 수정되었는가?
- 데이터 미변경 예시
- 캐시: 2020년 11월 10일 10:00:00 vs 서버 2020년 11월 10일 10:00:00
- 304 Not Modified, 헤더 데이터만 전송(바디 미포함)
- 전송 용량 0.1M(헤더 0.1M, 바디 1.0M)
- 데이터 변경 예시
- 캐시: 2020년 11월 10일 10:00:00 vs 서버 2020년 11월 10일
11
:00:00 - 200 OK, 모든 데이터 전송(바디 포함)
- 전송 용량 1.1M(헤더 0.1M, 바디 1.0M)
- 캐시: 2020년 11월 10일 10:00:00 vs 서버 2020년 11월 10일
- 데이터 미변경 예시
검증 헤더와 조건부 요청 단점
Last-Modified, if-Modified-Since
- 1초 미만(0.x초) 단위로 캐시 조정 불가능
- 날짜 기반 로직 사용
- 데이터를 수정해서 날짜가 달라지지만, 같은 데이터를 수정해서 데이터 결과가 같은 경우
- 해당 파일의 날짜는 변경이 되었지만 내용은 갱신이 되지 않은 경우
- 서버에서 별도의 캐시 로직을 관리하고 싶은 경우
- ex) 스페이스나 주석처럼 크게 영향이 없는 변경 시 캐시를 유지하고 싶은 경우 (ETag)
ETag, if-None-Match
- ETag(Entity Tag)
- 캐시용 데이터에 임의의 고유 버전명을 달아둠
- ex) ETag: “v1.0”, ETag: “tera_ver_01”
- 데이터가 변경되면 이 이름을 바꾸어서 변경(Hash 재생성)
- ex) ETag: “aaaa” -> ETag: “bbbb”
- 진짜 단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받는다
- 캐시 제어 로직을 서버에서 완전히 관리
검증 헤더 추가(첫번째 요청)
#응답
HTTP/1.1 200 OK
Content-Type: image/jpeg
cache-control: max-age=60
ETag: "aaaaaaaaaaa"
Content-Length: 34012
lkj123kjddhdudieidjskskdhdjd987snshsjdksjdjskdjakasks
skskdjdjsjkdkd938372sksksks;oisjsjdkds;skskdl;
- ETag: “aaaaaaaaaa”
- 종종 서버에서 ETag값을 내려주는 경우가 있다
- 클라에서는 해당 ETag값을 로컬에 저장 해둔다
- 해당 ETag 값을 통해 서버의 파일과 비교 한다
댓글남기기