Lined Notebook

[모든 개발자를 위한 HTTP 웹 기본 지식 강의] 14. 캐시기본동작과 조건부요청

by ymkim

✔ 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)

검증 헤더와 조건부 요청 단점

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 값을 통해 서버의 파일과 비교 한다

참고 자료

블로그의 정보

기록하고, 복기하고

ymkim

활동하기