캐시(Cache) 톺아보기(2) - 브라우저 캐시

date
Mar 19, 2024
slug
in-depth-cache-browser-cache
author
status
Public
tags
Network
summary
type
Post
thumbnail
PNG to WEBP conversion.webp
category
updatedAt
May 17, 2024 02:09 PM
 

FE는 캐시를 현명하게 다룰 줄 알아야 한다.

브라우저 캐시란?

웹 캐시의 일종입니다. 웹 캐시 또는 HTTP캐시는 서버 지연을 줄이기 위해 웹 페이지, 이미지, 기타 유형의 웹 멀티미디어 등의 웹 문서들을 임시 저장하기 위한 정보기술입니다. 브라우저 캐시는 브라우저나 HTTP요청을 하는 클라이언트 애플리케이션에 의해 내부 디스크에 이루어지는 캐시입니다. 이러한 캐시는 단일 사용자를 대상으로 하는 사설 캐시이며, 해당 사용자의 정보만을 저장합니다.
*HTTP 캐시들은 일반적으로 GET에 대한 응답만을 캐싱합니다.
기본 캐시 키(primary cache key)는 요청 메서드 그리고 대상 URI로 구성됩니다. (GET 요청만을 대상으로 하므로 URI만 사용되는 경우가 많습니다.)
웹 캐시는 레이턴시와 네트워크 트래픽을 줄여줌으로써 리소스를 보여주는 데에 필요한 시간을 줄여줍니다. ⇒ HTTP 캐싱을 활용하면 웹 사이트가 좀 더 빠르게 반응하도록 만들 수 있습니다.

어떻게 현명하게 다루죠?

1. 콘텐츠 유형별로 최적의 캐시 기간을 결정 (Next.js같은 프레임워크를 사용하는 것?)

콘텐츠 유형에 따라 최적의 캐시 기간을 결정합시다.동적인 콘텐츠는 짧은 캐시 수명을, 자주 바뀌지 않는 정적인 자산들은 더 오랜 기간 캐시합니다.

2. HTTP 캐싱 헤더 구현

Cache-Control, ETag, Last-Modified와 같은 HTTP 헤더를 활용하여 브라우저가 리소스를 캐시하는 방법과 시기를 제어합니다.

3. CDN사용

CDN이란 Content Delivery Network의 약자로, 분산 노드로 구성된 네트워크를 의미합니다. CDN은 성능 향상을 위해 클라이언트의 요청이 같은 서버로 가는 것을 막습니다. 각 지역의 엔드 유저에 따라 요청을 오리진 서버가 아닌 다른 서버로 가도록 분산시키는 역할을 합니다. 이 과정에서 캐싱이 사용되며, 사용자에게 더 가까운 엣지 위치에서 정적 콘텐츠를 캐시하여 전 세계 사용자의 대기 시간을 크게 줄이고 로드 시간을 향상시킬 수 있습니다.
e.g CDN 서비스하는 대표적인 회사 - Cloudflare(edge cache) / Aws cloudfront *edge cache - 네트워크의 엣지에서 정적 에셋 파일(이미지, CSS, JS)을 캐싱해서 엔드 유저에게 빠르게 도달하고, 콘텐츠 전송 시 서버 로드를 줄여주는 역할을 합니다.

4. 필요에 따라 서비스 워커 활용

캐시 버전을 명시적으로 관리하고, 캐시 전략에 대해 세부적인 제어를 할 수 있습니다. 서비스 워커 캐싱의 가장 중요한 이점 중 하나는 풍부한 오프라인 경험을 제공할 수 있다는 것입니다. 오프라인일 때 캐시된 콘텐츠를 제공하도록 애플리케이션을 설계하여 네트워크 연결 없이도 애플리케이션을 계속 사용할 수 있도록 할 수 있습니다. 서비스 워커는 동적 콘텐츠 캐싱을 허용합니다. 즉, 기존 브라우저 캐싱 메커니즘에서는 효과적으로 처리할 수 없는 API 호출 및 기타 런타임 리소스에서 가져온 데이터를 캐시할 수 있습니다.
 

캐시 관리를 위한 헤더 설정

Cache-control 헤더

HTTP/1.1 부터 사용 캐시의 생명주기, 타입 , 캐시 관리방법 정의 가능
*프로그램 성능과 관련해 ‘가장 빠른 코드는 실행하지 않는 코드다.’ 라는 말이 있습니다. 서버와 통신하지 않을 수 있다면, 그 방법이 성능 관점에서 가장 좋은 선택입니다.
HTTP/1.1 기본 헤더 필드는 요청과 응답 양측 모두에 있어 캐싱 메커니즘을 위한 디렉티브를 지정하는데 사용됩니다. 이 헤더 필드가 제공하는 여러 디렉티브들로 캐싱 정책을 정의하고자 한다면 이 헤더를 사용하시기 바랍니다.
*Pragma 헤더 - http/1.0 하휘 호환성을 위해 종종 사용됨
  • Cache-control: no-store → 캐시하지 않음 / 캐시는 클라이언트 요청 혹은 서버 응답에 관해서 어떤 것도 저장해서는 안됩니다. 요청은 서버 측으로 전송되고 전체 응답은 매번 다운로드됩니다. 응답에 대해 브라우저가 캐싱을 하지 않습니다. 매번 요청을 보낼 때마다 전체 데이터를 받아오는 식으로 처리하게 됩니다. 개인정보 등 private한 데이터가 있는 경우 이 속성을 사용할 수 있습니다.
  • Cache-control: no-cache → 캐시하지만 재검증 / 캐시된 복사본을 사용자에게 릴리즈 하기 전에, 유효성 확인을 위해 원 서버로 요청을 보냅니다. 서버에 이 캐시를 써도 되는지 허락을 맡고 쓰기에 요청에 대한 시간이 소요될 수 있습니다.
    • notion image

  • Cache-Control: public → 캐싱 가능 / 응답이 어떤 캐시에 의해서든 캐시되어도 좋다는 것을 가리킵니다. 이것은 HTTP 인증, 혹은 보통 캐시 가능하지 않은 응답 상태 코드를 지닌 페이지가 이제 캐시되어야 할 경우 유용할 수 있습니다.
  • Cache-Control: private → 엔드 유저만 캐싱 가능 / 응답이 단일 사용자만을 위한 것이며 공유 캐시에 의해 저장되어서는 안된다는 것을 가리킵니다. 사설 브라우저 캐시는 이런 경우에 응답을 저장할 수 있습니다.

  • Cache-Control: max-age → 리소스가 유효하다고 판단되는 최대 시간을 말합니다. 이 디렉티브는 요청 시간에 상대적이며, Expires가 설정되어 있어도 그보다 우선합니다. 변경되지 않을 파일에 대해, 공격적으로 (긴 시간으로) 캐싱할 수 있습니다. 예를 들어 이미지, CSS 파일 그리고 JavaScript 파일과 같은 정적 파일들입니다.
  • Cache-Control: Exipres → Cache-Control의 max-age보다 유연성이 저하됨. (max-age가 우선됨)

  • Cache-Control: must-revalidate → 캐시는 오래된 리소스를 사용하기 전에 그 상태를 확인하고 만료된 리소스는 사용하지 말아야 합니다. 캐시가 만료된 후 최초 조회시 원 서버에 검증을 반드시 거칩니다.이 속성은 만약 원 서버에 접근이 안된다면 504Gateway Timeout 에러가 발생합니다.캐시가 저장한 데이터를 사용할 때 stale(최신화가 필요한)이라는 표현을 사용하는데, 이러한 stale한 데이터를 쓰고 싶지 않을 때 must-revalidate속성을 사용하면 됩니다. no-cache와의 차이점은 프록시 캐시 서버와 원 서버 사이의 네트워크 단절이 일어난 경우에 발생한다는 것입니다. no-cache는 위에서 언급한 stale한 데이터라도 보여주어야 할 때 사용하고, 이러한 데이터를 사용해서 문제가 발생한다면 504에러를 반환하는 must-revalidate를 사용하면 됩니다.
 

캐시 유효 기간이 지난 이후에는? → 재검증!

캐시의 유효 기간이 지나면, 브라우저는 서버에 조건부 요청(Conditional request)을 통해 캐시가 유효한지 재검증(Revalidation)을 수행합니다.
notion image
 

캐시의 상태 - stale(실효) / fresh(유효)

서버는 리소스에 대한 만료 시간을 알려주는데, 만료 시간 이전에는 리소스가 유효(fresh)하고, 만료 시간 이후의 소스는 실효(stale)됩니다. 캐시가 stale한 리소스에 대한 요청을 받은 경우, 이 리소스가 유효한지 확인을 위해 If-None-Match와 함께 요청을 전달합니다.
 
[캐시 재검증 과정]
  1. 브라우저에서 GET요청이 발생하면 URI를 통해 브라우저 캐시 데이터를 먼저 탐색합니다.
  1. 캐시 데이터가 존재하지 않는다면 origin 서버로 요청을 보내고 응답을 받습니다.
  1. 캐시를 허용한 경우 해당 응답을 캐시에 저장합니다.
  1. 캐시 데이터가 존재한다면 해당 캐시 데이터가 신선한지 판별합니다.
  1. 신선하면 304 헤더를 돌려보내 대역폭을 절약합니다.
 

재검증 요청 헤더

ETag 와 Last-Modified 값은 기존에 받았던 리소스의 응답 헤더에 있는 값을 사용합니다.
notion image

1. If-Modified-Since (Request header)

Response Header로 받은 Last-Modified 값 이후 서버 리소스가 수정되었는지 확인합니다. 만약 수정되지 않는 리소스에 대한 요청시, 리소스 없이 304 응답을 하게 됩니다. 이전 요청의 Last-Modified 응답 헤더는 마지막으로 수정 한 날짜를 포함합니다.
 
- Last-Modified (Response header) 원본 서버가 리소스가 마지막으로 수정되었다고 생각하는 날짜와 시간이 포함되어 있습니다. 리소스가 이전에 저장된 리소스와 동일한지 확인하기 위한 유효성 검사기로 사용됩니다.  *ETag 헤더보다 정확하지는 않습니다.
Last-Modified 헤더가 응답 내에 존재하면, 클라이언트는 캐시된 문서를 검증하기 위해 If-Modified-Since 요청 헤더를 줄 수 있습니다.
 
*Last-Modified는 크롤러가 크롤링 빈도를 조정할 때, 브라우저가 휴리스틱 캐싱을 할 때, 콘텐츠 관리 시스템(CMS)이 콘텐츠가 마지막으로 수정된 시간을 표시할 때에도 사용됩니다.
휴리스틱 캐싱
원래 서버가 명시적으로 유효성을 지정하지 않았으면 (예를 들어 Cache-Control 또는 Expires 헤더를 사용해서), 휴리스틱으로 유효 기간을 추정합니다.
이 경우에는 Last-Modified 헤더를 찾습니다. 이 헤더가 있다면, 캐시의 유효 수명은 Date 헤더 값에서 Last-modified 헤더 값을 뺀 값을 10으로 나눈 결과가 됩니다. 만료 시간은 다음과 같이 계산됩니다:
 

 

2. If-None-Match (Request header)

 
notion image
 
notion image
 
- ETag(Entity tag)
ETag(HTTP 헤더의 ETag)는 특정 버전의 리소스를 식별하는 역할을 하는 고유 식별자(데이터의 버전 이름 혹은 해시값) 입니다. 서버는 파일이 변경될 때마다 새 ETag 값을 생성합니다. 내용을 확인하고 변하지 않았다면, ETag는 동일한 값을 그대로 유지하게 되며, 이를 통해 웹 서버로 전체 요청을 보내지 않아도 되므로 캐시 관리가 효율적으로 이루어집니다. 요구사항에 따라 서버에서 ETag가 무기한 지속되도록 설정하는 것도 가능합니다. 또한, 캐싱된 리소스가 불러온 리소스와 일치하는지를 확인할 수 있습니다. ETag 값은 개발자가 지정하여 사용할 수 있으며, 버전명, 컨텐츠의 해시값 등으로 정할 수 있습니다.
 

재검증 과정

  1. 다음에 동일한 자원에 대한 요청을 보낼 때, 리소스 변경 여부를 확인하기 위해 요청 헤더의 If-None-Match 값에 저장해두었던 ETag를 함께 실어보냅니다. 응답을 통해 받아 놓았던 Etag의 값을 요청 헤더의 If-None-Match에 실어 요청을 보냅니다.
    1. notion image
  1. 서버에서 If-None-Match 헤더를 포함한 요청을 받으면, 서버 측의 ETag 값과 요청 헤더의 값을 비교합니다. → 그 값이 서로 동일하면, 304 코드와 함께 비어있는 body를 보냅니다.
    1. notion image
  1. 브라우저에서는 응답 코드가 304라면 캐시된 자원을 사용합니다. → 매우 빠름 (본문이 없기에) 서버에서는 클라이언트의 ETag를 현재 버전 리소스의 ETag와 비교하고, 일치한다면 현재 ETag가 유효하며 리소스의 변경이 없다는 의미입니다. 이때 304(Not Modified) 상태코드를 내려줍니다. 304응답이 오면 브라우저는 캐시 데이터의 헤더를 반환받은 응답의 http 헤더로 교체하여 원본 데이터가 아닌 캐시 정보에 대한 헤더만 변경합니다.
  1. 만약 ETag 값이 일치하지 않으면(검증 헤더를 통해 확인 시 결과 데이터가 변경된 경우) 200 코드와 함께 요청된 자원을 body에 실어보냅니다. 이 데이터를 다시 캐싱할 수 있게 됩니다.
  1. 서버 측 변경 사항을 적용하는 경우라면 412 코드(access-denied)를 반환합니다.
  1. ⇒ Content가 변하지 않았다면 웹 서버가 전체 response를 전송할 필요가 없습니다.
  1. ❗여러 대의 서버를 운영하고 있다면 같은 컨텐츠이지만 ETag가 다를 수 있습니다.
 
 
출처