웹 어플리케이션에서는 네트워크 요청을 통해 필요한 리소스들을 받아옵니다. 만약 다음 요청에서 응답받을 리소스가 이전 요청에서 응답받은 리소스와 동일할 경우, 동일한 리소스에 대한 네트워크 요청은 응답 시간을 지연시킬 뿐더러 불필요한 네트워크 요청으로 서버의 자원을 낭비하게 됩니다. 이러한 경우에 HTTP 캐싱을 활용하면 이전에 가져온 리소스들을 재사용함으로써 웹 어플리케이션의 성능을 현저하게 향상시킬 수 있습니다. HTTP 캐시를 효율적으로 관리하기 위해서는 Cach-Control 헤더를 섬세히 조절해야 합니다.
💡 리소스(Resource)
HTTP 요청 대상으로, 텍스트, 이미지, 파일 등 식별 가능한 모든 자원을 말한다.
🕰️ Cache-Control
웹 브라우저가 지금껏 요청한 적이 없는 리소스를 서버에서 가져오려고 할 때, 서버와 브라우저는 완전한 HTTP 요청/응답을 주고 받습니다. 이후 HTTP 응답에 포함된 Cache-Control 헤더에 따라 받은 리소스의 생명 주기가 결정됩니다.
Cache-Control 헤더 필드는 브라우저 및 공유 캐시(ex. proxies, CDNs)의 캐싱을 제어하는 요청 및 응답 모두에서 사용할 수 있습니다.
🧚🏻♀️ Response Directives
max-age
max-age는 브라우저에 캐시되는 유효 기간을 나타냅니다. max-age=N은 응답이 생성된 후 N초까지 응답이 fresh 상태임을 의미합니다.
캐시의 유효 기간이 지나기 전: 재사용
Cache-Control 응답 헤더 값이 max-age=59이기 때문에 응답이 생성된 후 59초까지는 캐시된 응답을 재사용합니다.
캐시의 유효 기간이 지난 후: 재검증
캐시의 유효 기간이 지나면 브라우저는 서버에 캐시가 유효한 지에 대한 재검증 요청을 보냅니다. 재검증 결과 브라우저의 캐시가 유효하다면 서버는 [304 Not Modified] 응답을 내려줍니다. [304 Not Modified] 응답은 HTTP 본문을 포함하지 않기 때문에 빠른 응답을 받을 수 있습니다.
5.5KB 리소스의 캐시 검증을 위해 206B 사이즈만이 네트워크의 통신에 사용되었음을 알 수 있습니다.
재검증 결과 브라우저의 캐시가 유효하지 않다면 [200 OK] 또는 적합한 상태 코드를 본문과 함께 내려줍니다. 추가로 HTTP 요청을 보내지 않고도 최신값을 내려받을 수 있기 때문에 효율적입니다.
s-maxage
s-maxage는 CDN(클라이언트와 서버의 중간 서버)에 캐시되는 유효 기간을 나타냅니다.
max-age와 유사하지만 s-maxage는 공유 캐시에만 적용되며 max-age가 존재하는 경우 max-age를 무시합니다.
no-cache
no-cache는 응답이 캐시에 저장될 수 있음을 나타내지만, 캐시를 재사용하기 전에 원본 서버에서 응답의 유효성을 검사해야 합니다. 저장된 콘텐츠를 재사용하는 동안 캐시가 항상 콘텐츠의 업데이트 여부를 확인하도록 할 때 유용하게 사용할 수 있습니다.
no-store
no-store은 어떤 종류의 캐시(private 또는 shared)도 이 응답을 저장하지 않아야 함을 나타냅니다. 응답을 캐시해서는 안 되는 리소스일 경우 사용합니다.
private
private은 응답이 개인 캐시(ex. 브라우저의 로컬 캐시)에만 저장될 수 있음을 나타냅니다.
📍 개인화된 콘텐츠, 특히 로그인 후 수신된 응답과 쿠키를 통해 관리되는 세션에 대해 private을 추가해야 합니다. 이를 잊은 경우 해당 응답이 공유 캐시에 저장되어 여러 사용자로 인해 재사용될 수 있으며, 이로 인해 개인 정보가 유출될 수 있습니다.
public
public은 응답이 공유 캐시에 저장될 수 있음을 나타냅니다.
📍 인증 헤더 필드에 있는 요청에 대한 응답은 공유 캐시에 저장해서는 안 됩니다. public은 이러한 응답을 공유 캐시에 저장되도록 합니다.
📝 예제
Cache-Control: public, max-age=604800
📍 s-maxage 또는 must-revalidate는 위의 규정을 해제합니다. 요청에 인증 헤더가 없거나 이미 응답에서 s-maxage 또는 must-revalidate를 사용하고 있다면 public을 사용할 필요가 없습니다.
must-revalidate
must-revalidate는 응답을 캐시에 저장할 수 있으며 캐시가 신선한 동안 응답을 재사용할 수 있음을 나타냅니다. 응답이 오래된 경우, 재사용하기 전에 원본 서버에서 유효성을 검사해야 합니다. 일반적으로 max-age와 함께 사용합니다.
📝 예제
Cache-Control: max-age=604800, must-revalidate
💡 HTTP는 원본 서버와의 연결이 끊어졌을 때 캐시에서 오래된 응답을 재사용하는 것을 허용합니다. must-revalidate는 이러한 해프닝을 방지하는 방법입니다. 저장된 응답이 원본 서버로 재검증되거나 504(Gateway Timeout) 응답이 생성됩니다.
stale-while-revalidate
stale-while-revalidate는 캐시에 대한 유효성을 재검증하는 동안 오래된 응답을 재사용할 수 있음을 나타냅니다.
📝 예제
Cache-Control: max-age=604800, stale-while-revalidate=86400
위의 예제에서는 응답이 7일(604800s) 동안 신선합니다. 7일 후에는 오래되지만 백그라운드에서 응답을 재검증하는 경우 다음 날(86400s) 어떤 요청에 대해서든 캐시가 재사용될 수 있습니다. 유효성 재확인은 캐시를 다시 최신 상태로 만들어 클라이언트에게 해당 기간 동안 항상 최신 상태인 것처럼 보이게 하여 재확인으로 인한 대기 시간 페널티를 효과적으로 숨깁니다. 해당 기간 동안 요청이 발생하지 않으면 캐시가 오래되어 다음 요청이 정상적으로 재검증됩니다.
'Web' 카테고리의 다른 글
[AWS] 웹 어플리케이션 배포하기 (EC2) (0) | 2023.05.03 |
---|