HTTP 캐싱

장찬우·2025년 2월 10일
post-thumbnail

HTTP 캐싱이란?

HTTP 캐싱은 웹 리소스(이미지, 스크립트, HTML 등)의 복사본을 저장하고 재사용하는 기술이다.
이를 통해 서버 부하를 줄이고, 성능을 향상시키며, 사용자 경험을 개선할 수 있다.
캐시가 없으면 사용자는 느린 로딩 속도를 경험 할 수 있으며, 캐싱은 이런 문제를 해결하는 핵심 솔루션 입니다.


1. HTTP 캐싱의 기본 원리

HTTP 캐싱은 네트워크 상에서 요청과 응답을 저장하고 재사용하며 크게 두가지 목적을 가지고 있다.

  1. 네트워크 대역폭 절약
  2. 지연시간 감소

캐시가 없다면?
클라이언트 요청 → 네트워크 통신 → 서버 처리 → 네트워크 통신 → 클라이언트 수신

캐시 사용시
클라이언트 요청 → 로컬 캐시 확인 → 즉시 응답


2.캐시의 종류와 특징

프라이빗 캐시란?

프라이빗 캐시는 우리가 매일 사용하는 웹 브라우저에 저장되는 캐시를 말한다. 크롬이나 사파리 같은 브라우저로 웹사이트를 방문할 때, 브라우저는 웹페이지의 이미지, 스타일시트, 자바스크립트 파일 등을 로컬에 저장해둔다.
프라이빗 캐시는 개인적인 용도로 사용된다. 다른 사용자는 내 브라우저의 캐시를 볼 수 없고, 나도 다른 사람의 캐시를 볼 수 없다.
프라이빗 캐시의 가장 큰 장점은 개인화된 데이터를 안전하게 저장할 수 있다는 점이다. 로그인 정보나 개인 설정 같은 민감한 정보도 프라이빗 캐시에 저장할 수 있다.

공유캐시란?

공유 캐시는 여러 사용자가 함께 사용하는 캐시다. 대표적인 예로 CDN(Content Delivery Network)이나 프록시 서버의 캐시가 있다.
공유 캐시는 많은 사용자가 혜택을 볼 수 있도록 설계되었다.
공유 캐시는 대규모 웹 서비스에서 중요한 역할을 한다. 유튜브의 인기 동영상이나 네이버의 메인 로고 같은 많은 사람이 보는 콘텐츠는 공유 캐시를 통해 더 빠르게 제공될 수 있다.

1. 접근범위
프라이빗 캐시: 단일 사용자만 접근
공유 캐시: 여러 사용자가 접근
2. 저장 데이터
프라이빗 캐시: 개인화된 데이터 포함 가능
공유 캐시: 공개된 데이터만 저장


3.캐시의 생명 주기

웹브라우저가 새로운 리소스를 가져오려고 할 때, 서버와 브라우저는 HTTP요청/응답을 주고 받는다. 이때, HTTP응답에 포함된 Cache-Control 헤더에 따라 받은 리소스의 생명 주기가 결정된다.

캐시의 유효기간:max-age

서버의 Cache-Control 헤더의 값으로 max-age = seconds 값을 지정하면 이 리소스의 캐시가 유효한 시간은 seconds초가 된다.

s-maxage(shared maxage)

중간 서버에서만 적용되는 max-age 값을 설정하기 위해 s-maxage 값을 사용할 수 있다.
예를 들어, Cache-Control 값을 s-maxage=31536000, max-age=0 과 같이 설정하면 CDN에서는 1년동안 캐시되지만 브라우저에서는 매번 재검증 요청을 보내도록 설정할 수 있다.

캐시의 유효 기간이 지나기 전

한 번 받아온 리소스의 유효 기간이 지나기전이면, 서버에 요청을 보내지 않고 디스크 또는 메모리에서만 캐시를 읽어와 계속 사용한다.

1) Memory Cache

  • RAM에 저장되어 가장 빠른 접근 가능
  • 브라우저 세션 동안만 유지
  • 주로 자주 사용되는 작은 리소스에 사용

2) Disk Cache

  • 하드 디스크에 저장되어 브라우저를 닫아도 유지
  • Memory Cache보다 느리지만 용량이 큼
  • 이미지, CSS, JS 파일 등 큰 리소스 저장에 적합


개발자도구에서 이 리소스가 가지는 Cache-control헤더 값은 max-age=315360000이기때문에 10년동안 캐시할 수 있다. 스크린샷을 보면 캐시가 남아있기때문에 from memory cache라고 표기된 것을 볼 수 있다.

Cache-Control max-age 값 대신 Expires 헤더로 캐시 만료 시간을 정확히 지정할 수도 있다.

재검증(Revalidation) 과정

캐시의 유효기간이 지난다고 해서 완전히 사라지진 않는다. 대신 브라우저는 서버에 캐시가 유효한지 재검증을 수행한다.

1. ETag를 이용한 방식

  • 서버가 리소스에 고유한 식별자(ETag) 할당
  • 클라이언트는 'If-None-Match' 헤더로 ETag 값 전송
  • 서버는 현재 리소스의 ETag와 비교
    ex) If-None-Match: "abc123"

2. Last-Modified를 이용한 방식

  • 서버가 리소스의 마지막 수정 시간 전송
  • 클라이언트는 'If-Modified-Since' 헤더로 시간 전송
  • 서버는 현재 리소스의 수정 시간과 비교
    ex) If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT

정적리소스의 경우(로고, reset css) 잘 변경되지 않는 리소스는 긴 시간으로 설정한다. 반대로 자주 변경되는(api데이터)리소스는 짧은 시간이나 즉시 만료를 설정한다.
너무 긴 설정은 콘텐츠의 업데이트를 방해할 수 있고, 너무 짧은 설정은 캐시의 이점을 살리지 못하므로 적절한 사용이 중요시된다.

검증(Validation)

검증은 캐시된 리소스가 여전히 유효한지 확인하는 과정이다. 강한 검증(Strong Validator)과 약한 검증(Weak Validator)이 있는데, 강한 검증은 리소스의 비트 단위 수준까지 정확하게 일치하는지 확인한다. 예를 들면 금융거래, 의료정보, API응답데이터 등이 있다. 반면 약한검증은 약한 검증자는 리소스의 의미론적 동등성을 검사한다. 즉, 작은 변화는 무시하고 실질적인 내용 변화만을 감지한다. 예로 뉴스기사, 블로그 포스트, 동적으로 생성되는 페이지가 있다.

캐시의 위치


CDN과 같은 중간 서버를 사용할때 캐시는 여러곳에 생기는데, 서버가 가지고있는 캐시를 CDN이 캐시하고 CDN의 캐시된 응답은 브라우저가 다시 가져와서 캐시한다.

CDN Invalidation

일반적으로 캐시를 없애기 위해서 “CDN Invalidation”을 수행한다고 얘기하는데, CDN Invalidation은 위 이미지에서 가운데에 위치하는 CDN에 저장되어 있는 캐시를 삭제한다는 의미이다. 브라우저의 캐시는 다른 곳에 위치하기 때문에 CDN 캐시를 삭제한다고 해서 브라우저 캐시가 삭제되지는 않는다.

경우에 따라 중간 서버나 CDN이 여러 개 있는 경우도 발생하는데, 이 경우 전체 캐시를 날리려면 중간 서버 각각에 대해서 캐시를 삭제해야 한다.

이렇게 한번 저장된 캐시는 지우기 어렵기 때문에 Cache-Control의 max-age 값은 신중히 설정하여야 한다.

Cache-Control: public과 private

CDN과 같은 중간 서버가 특정 리소스를 캐시할 수 있는지 여부를 지정하기 위해 Cache-Control 헤더 값으로 public 또는 private을 추가할 수 있다.(2번항목 캐시의 종류와 특징과 같다.)

public은 모든 사람과 중간 서버가 캐시를 저장할 수 있음을 나타내고, private은 가장 끝의 사용자 브라우저만 캐시를 저장할 수 있음을 나타낸다.

기존과 max-age 값과 조합하려면 Cache-Control: public, max-age=86400 과 같이 콤마로 연결할 수 있다.

마치며

HTTP 캐싱은 웹 개발에서 매우 중요한 개념이다. 프라이빗 캐시와 공유 캐시를 통해 개인화된 데이터와 공용 데이터를 효율적으로 관리할 수 있다.
특히 캐시의 신선도 관리는 서비스의 성능과 직결된다. 너무 긴 캐시 유효 기간은 오래된 데이터를 보여줄 수 있고, 너무 짧은 기간은 캐시의 이점을 살리지 못한다. 따라서 리소스의 특성에 맞는 적절한 캐시 전략을 선택하는 것이 중요하다.


참조 출처
https://httpwg.org/specs/rfc9111.html
https://requestmetrics.com/web-performance/http-caching/
https://f-lab.kr/insight/http-caching-and-cdn
https://toss.tech/article/smart-web-service-cache

profile
프론드엔드 개발자가 되기위한 기록

0개의 댓글