봄디의 개발일지
[HTTP] HTTP 헤더 - 캐시의 기본 동작 (검증 헤더 Last-Modified) 본문
1️⃣ 만약 캐시가 없다면 ?
웹 브라우저가 star.jpg 라는 이미지를 서버에 요청을 했을 때 서버는 star.jpg 파일을 내려주고,
HTTP 헤더와 star.jpg 에 관련된 내용이 들어있는 HTTP 바디를 포함한 HTTP 응답 메시지를 내려줄 것입니다.
이 때, HTTP 헤더는 0.1M , HTTP 바디는 1.0M 라고 가정을 하겠습니다.
만약, GET /star.jpg 라고 다시 웹 브라우저가 서버에게 요청을 한다면 서버는 다시 동일한 HTTP 응답 메시지를 만들어서 웹 브라우저에게 내려줄 것입니다. 이 때도 마찬가지로 1.1 M 를 사용하게 될 것입니다.
(HTTP 헤더 0.1M + HTTP 바디 1.0M)
이처럼 캐시가 없다면 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운로드 받아야 하는 문제점이 있습니다. 인터넷 네트워크는 매우 느리고 비싸기 때문에 동일한 데이터를 계속 다운받는건 불필요하며, 브라우저의 로딩 속도가 느리기 때문에 사용자 역시 느린 경험을 하게 됩니다.
2️⃣ 캐시를 적용했을 때
서버에서 캐시를 적용할 경우 cache-control 이라는 정보를 추가하여 HTTP 헤더에 넣어줄 수 있습니다.
cache-control 은 캐시가 유효한 시간을 나타내며, max-age=60 은 60초동안 캐시가 유효하다는 것을 의미합니다.
60초가 유효한 응답 결과를 캐시에 저장을 해놓고, 두 번째로 GET /star.jpg 와 같은 동일한 요청이 들어온다면 브라우저 캐시에서 먼저 찾아 유효시간이 지났는 지를 확인한 후, 유효시간이 지나지 않았다면 바로 캐시에서 가져와서 사용한다.
브라우저 캐시에서 해당 내용을 찾게 되면 비싼 네트워크 사용량도 줄일 수 있고 브라우저의 로딩 속도 역시 빨라지기에 사용자 역시 빠른 경험을 할 수 있습니다.
그런데, 만약 캐시의 유효시간이 초과되었다면 ?
클라이언트에서 서버에 다시 요청을 해서 데이터를 내려주면, 또 캐시를 사용하여 브라우저 캐시에 새로운 캐시로 덮어 씌우게 됩니다.
이 과정에서 역시 다시 네트워크는 1.1M 를 사용하게 됩니다.
그러나, 동일한 star.jpg 의 데이터를 내려주었기 때문에 이미지는 바뀌지 않았습니다. 이럴 때 1.1M 의 파일을 다시 다운로드 받을 필요가 있을까요 ?
캐시 유효 시간이 초과해서 서버에 다시 요청을 하면, 두 가지 상황이 나타날 수 있습니다.
- 서버에서 기존의 데이터를 다른 데이터로 변경한 경우
- 서버에서 기존 데이터를 변경하지 않은 경우
데이터가 바뀌지 않은 경우 캐시 데이터가 바뀌지 않았다는 사실을 확인할 수 있는 방법인 검증 헤더가 추가가 됩니다.
✅ 서버에서 기존 데이터를 변경하지 않은 경우
HTTP 메시지에 Last-Modified 라고 해서 데이터가 마지막에 수정된 시간을 추가합니다.
앞과 마찬가지로 서버에서 응답 데이터를 캐시에 저장하고, 유효 시간은 60초입니다.
두번 째 요청에서 동일하게 GET /star.jpg 를 요청하는 경우 브라우저 캐시에서 찾게 되는데 이미 유효 시간이 60초가 지난 경우,
이 캐시의 Last-Modified 정보를 확인합니다.
브라우저 캐시에서 Last-Modified 로 확인한 정보를 웹 브라우저가 서버에 요청을 보낼 때 if-modified-since 라는 HTTP 요청 헤더를 붙인 다음에 서버에 전달합니다.
서버에서는 star.jpg 의 정보를 확인하여 최종 수정일이 클라이언트가 보낸 요청과 날짜가 동일한 지 확인을 하고 캐시를 사용해도 되는 지의 여부를 웹 브라우저에게 전달을 합니다.
캐시를 그대로 사용해도 되는 경우 서버에서는 응답 메시지를 생성할 때 304 Not Modified 를 사용해서 웹 브라우저에게 변경된 것이 없다는 정보를 알려주고, 데이터 정보를 제외한 (HTTP Body 제외) HTTP 헤더만을 웹 브라우저로 전송합니다.
캐시의 유효시간이 초과되어도 서버의 데이터가 갱신되지 않을 경우 서버는 304 Not Modified 와 함께 HTTP 헤더 메타 정보만을 응답합니다.
클라이언트는 서버가 보낸 응답 헤더 정보로 캐시의 메타 정보를 갱신하고, 캐시에 저장되어 있는 데이터를 재활용하게 됩니다.
결과적으로 네트워크 다운로드가 발생하긴 하지만 용량이 적은 헤더의 정보만을 다운로드하기 때문에 매우 실용적인 해결책이 될 수 있습니다.
즉, 검증헤더는 캐시 데이터와 서버 데이터가 같은 지를 검증하는 데이터이며 크게 두 가지가 있습니다.
- Last-Modified (위에서 설명)
- ETag
Last-Modified 는 위에서 설명했던 것처럼 if-modified-since 와 같이 사용되며
ETag 는 if-none-match 와 같이 사용됩니다.
if-modified-since 이후에 데이터가 수정이 되었다면 304 Not Modified 와 헤더 데이터만 전송하고,
데이터가 수정이 되었다면 200 OK 를 내려주게 되고 서버에서는 모든 데이터를 다시 전송하게 됩니다.
✅ Last-Modified 와 if-modified-since 의 단점
Last-Modified 와 if-modified-since 를 사용하는 경우 1초 미만 단위로 캐시 조정이 불가능하며, 날짜 기반의 로직을 사용해야 합니다. 날짜는 갱신이 되어있지만 실제 컨텐츠는 갱신이 되어 있지 않은 경우에도 날짜 기반으로 확인하기 때문에 전체 데이터를 다시 다운로드 받게 되는 문제점이 발생할 수 있습니다.
이런 단점을 극복할 수 있고 서버에서 별도의 캐시 로직을 관리하고 싶은 경우 사용하는 방법이 바로 ETag 입니다.
다음 포스팅에서 ETag 와 If-None-Match 에 대해 설명해드리겠습니다.
🔍 참고글
인프런 김영한 강사님의 [모든 개발자를 위한 HTTP 웹 기본 지식] 섹션 9. HTTP 헤더2 - 캐시와 조건부 요청 강의를 참고하여 작성했습니다.
'HTTP' 카테고리의 다른 글
[HTTP] 캐시 제어 헤더 (Cache-Control, Pragma, Expires, 프록시 캐시 서버) (0) | 2024.10.20 |
---|---|
[HTTP] HTTP 헤더 - 검증 헤더 (ETag, If-Node-Match) (2) | 2024.10.20 |
[HTTP] HTTP 헤더 - 쿠키 (1) | 2024.10.13 |
[HTTP] HTTP 헤더 - 일반 헤더 (전송 방식 / 일반 정보 / 특별한 정보) (3) | 2024.10.13 |
[HTTP] HTTP 헤더 - 일반 헤더 (표현/협상) (4) | 2024.10.06 |