개발/이미지 최적화

[HTTP] 브라우저 이미지 캐시를 공부하다가 알게 된 ETag

dev_jiwonpark 2025. 10. 23. 19:52

 

이미지 최적화를 공부하다 보면 “브라우저 캐시”라는 개념을 피할 수 없다.
이미 한 번 불러온 이미지를 다시 다운로드하지 않고, 브라우저가 저장해두었다가 재사용하는 방식이다.
그런데 문득 이런 의문이 들었다.

“이미지가 바뀌면, 브라우저는 그걸 어떻게 알아차릴까?”

이 궁금증을 따라가다 보니 결국 ETag(Entity Tag) 라는 개념을 만나게 됐다.
ETag는 HTTP 응답 헤더 중 하나로, 특정 버전의 리소스를 식별하는 식별자다.
서버는 파일의 버전에 따라 고유한 ETag 값을 생성하고, 브라우저는 그 값을 기억해둔다.

 

이번에는 Etag에 대해서 공부한 내용을 정리해보려고 한다.


ETag란?

ETag는 서버가 응답을 보낼 때 리소스(이미지, HTML, JS, CSS 등)에 대한 고유한 식별자를 함께 전달하는 방식이다.

브라우저는 이후 같은 URL을 요청할 때 If-None-Match 헤더에 이전 ETag를 포함해 보낸다.

 

서버는 이 값을 비교하여 리소스가 변경되지 않았다면 304 Not Modified 응답을 반환하고, 

클라이언트는 이를 확인하고 저장된 자료인 캐시를 활용한다.

HTTP/1.1 304 Not Modified


새로운 버전이라면 200 OK와 함께 최신 리소스를 다시 내려준다.

 

 

한마디로 파일이 바뀌지 않았다면, 다시 다운로드하지 않아도 된다 는 걸 ETag로 판단하는 것이다.
이 덕분에 불필요한 트래픽이 줄고, 대역폭을 절약할 수 있다.

 

우선 내가 참고했던 mdn 웹사이트의 응답 & 요청 header를 살펴보았다.

응답 헤더를 보면 실제로 Etag는 W/"d801a096f0b3194963a651abcf814242" 로 되어있었고

컨텐츠가 변경되지 않았는지 응답 status 304 Not Modified 이다. 

요청 Header에는 method가 Get이고  If-None-Match 에 Etag 값이 포함되어 있는걸 확인할 수 있었다.

ETag의 문법과 구조 는 아래와 같다.

ETag: W/"<etag_value>"
ETag: "<etag_value>"
  • W/ (optional) : Weak validator를 의미한다.
    Weak ETag는 생성은 간단하지만 바이트 단위 비교는 어렵다. 때문에 거의 비슷한 경우까지 허용하는 비교 방식이다.
    반대로 Strong ETag는 정확한 비교가 가능하지만 생성 비용이 높다.
  • "<etag_value>" : 보통 리소스의 해시나 수정 시간 등을 기반으로 생성된 고유 문자열이다.
Strong ETag "abc123" 파일의 내용이 완전히 동일해야 같다고 판단
Weak ETag W/"abc123" 내용이 거의 같지만 바이트 단위로는 다를 수도 있음 (예: 공백, 주석 등 차이)

 

ETag: "abc123"
ETag: W/"abc123"

즉, 서버는 파일의 버전을 고유하게 식별할 수 있는 ‘지문’을 만들어 클라이언트에 전달하는 셈이다.

 

동시 수정 충돌 방지 (Mid-Air Collisions)

ETag는 단순히 캐싱 효율을 위한 기능을 넘어,
동시에 여러 사용자가 같은 리소스를 수정할 때 발생할 수 있는 충돌을 방지하는 용도로도 쓰인다.

 

예를 들어, 위키 페이지를 편집할 때 현재 콘텐츠의 ETag가 아래와 같다면

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"


이 값은 If-Match 헤더를 통해 아래와 같이 서버로 함께 전송된다.

If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

 

서버는 이 값을 비교해 문서가 이미 다른 사람에 의해 변경된 상태라면
412 Precondition Failed 응답을 보내 수정 충돌을 막는다.

 

정리하자면 If-None-MatchIf-Match는 모두 클라이언트(브라우저)가 서버에 보내는 요청 헤더이다.

 

  • If-None-Match → GET 요청 시 사용, 내가 가진 캐시가 최신인건지?
  • If-Match → PUT/PATCH 요청 시 사용, 내 버전이 최신일 때만 수정할게

 

즉, 서버는 ETag를 발급하고,
클라이언트는 이를 기반으로 리소스의 최신 여부를 확인하거나 충돌을 방지하는 것이다.


 

이미지 최적화를 공부하다가 자연스럽게 캐싱과 ETag까지 이어졌는데,

결국 브라우저가 무엇이 바뀌었는가를 판단하는 과정은 생각보다 디테일 했다.

ETag는 단순히 캐싱 효율을 높이는 기능이 아니라, 서버와 브라우저가 리소스의 동일성을 판단하기 위한 약속인 것 이다.
이 덕분에 불필요한 요청은 줄고, 네트워크는 훨씬 가벼워진다. 이제는 “이미지 최적화”를 생각할 때 단순히 파일 용량만 보는 게 아니라,
서버와 브라우저가 효율적으로 요청 & 응답을 하는지까지 생각해봐야한다는것을 알게 되었다.

 

 

 

 

 

 

[참고]

https://developer.mozilla.org/ko/docs/Web/HTTP/Reference/Headers/ETag

 

ETag - HTTP | MDN

ETag와 HTTP헤더의 If-Match를 이용하여 충돌을 예측할 수 있습니다. 예를 들어 MDN을 편집할 때, 현재 위키 콘텐츠는 해시되어 Etag 안에 들어갑니다. ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4" 위키 페이지

developer.mozilla.org

https://yozm.wishket.com/magazine/detail/1772/

 

Etag를 이용하여 더 나은 Restful API 만들기 | 요즘IT

요즘 웹 개발자라면 Restful API를 한 번쯤 다뤄본 경험이 있을 것입니다. HTTP 사양의 주요 저자 이자 REST를 세상에 처음 알린 ‘로이 필딩(Roy Fielding)이 주장하는 REST 아키텍처 구성요소는 잘 몰라도

yozm.wishket.com