Web Cache

CheolHyeon Park·2022년 11월 28일
0

기초지식

목록 보기
11/15

웹 캐시(Web-cache)는 웹에서 사용하는 캐시를 뜻한다. 캐시가 뭘까?

캐시란?
데이터나 값을 미리 복사해두어 사용하는 장소를 뜻한다. 어떤 값을 다시 계산하는 시간을 줄이기 위해 캐시를 사용한다. - https://ko.wikipedia.org/wiki/캐시

캐시가 된 리소스는 서버에 해당 리소스를 요청하지 않고 캐싱된 리소스를 사용한다. 이러한 웹 캐시는 주로 서버의 부하를 줄이기 위해 사용하거나 응답시간을 빠르게 하기 위해 사용하게 된다. 캐시의 사용전략이 곧 성능의 향상이나 리소스 낭비를 줄이는 방법이 될 수 있다.

대표적인 헤더

Cache-Control

캐시에 관한 설정을 하는 대표적인 헤더이다. Cache-Control 의 사용되는 값들을 살펴보자.

max-age

캐시의 유효기간을 설정하는 값이다. max-age=<seconde> 로 사용된다.

s-maxage

CDN과 같은 중간 서버를 두는 경우, 해당 서버의 캐시 유효기간을 설정할 때 사용한다.

private vs public

캐싱을 해야할 정보가 다른 곳에는 캐싱되지 않고 오직 해당 브라우저에만 캐싱되도록 하려면 private 을 사용해야한다.

반대로 public 을 사용한다면 다른 클라이언트들도 해당 리소스를 캐싱하게 된다.

no-cache vs no-store

모든 response를 새로운 response를 받기 위해 사용하는 것이 no-cache 이다. no-cache 방식은 max-age=0 을 설정한 것과 같은 효과를 가진다. no-cache 와 헷갈리는 것이 no-store 다. 이 방식은 아예 캐시를 저장하지 않는 방식이다. no-cache 보다 no-store 를 사용하는 것이 좋다. (아래 설명하겠다.)

Immutable

해당 리소스의 변경이 없을 때 사용한다. 이 리소스는 항상 캐싱해두고 사용하게 된다. 또한, reload나 브라우저 종료에 의해서도 지워지지 않는다.

must-revalidation

revalidation을 진행한다. 재 검증을 통해 해당 리소스가 유효한지 체크하게 된다.


Expired

max-age와 같이 캐시의 유효기간을 설정하는 헤더. 만료되는 날짜를 기록한다. 하지만 날짜는 오류가 발생가능성이 크기 때문에 권장은 max-age로 하는 것이 권장된다.


Vary

같은 URL에 다른 식별자를 적용하여 캐싱하고 싶을 때 사용한다. 예를 들면 https://example.com/index.html 과 같은 페이지를 가져올 때, 한글이냐 영문이냐에 대한 정보를 같이 캐싱하고 싶을 수 있다. 이 때 Vary: Accept-Language 로 값을 설정한다면 Accept-Language 에 따라 다른 정보를 캐싱할 수 있게 된다.

Vary: Accept-Language

If-Modified-Since

response가 stale해지면 해당 response를 재사용하지 않는다. response를 revalidation하기 위해 서버에 If-Modified-Since 값을 보내서 확인하게 된다. 서버에서 변경사항이 없다면 304(Not Modified)를 보내게 되고 클라이언트는 response에 대한 정보를 갱신하여 저장하고 다음 캐시 갱신 전까지 이 정보를 사용하게 된다.


If-None-Match와 ETag

response가 stale해지면 캐시가 유효한지 검증하기 위해 revalidation을 진행한다. 이 때 사용하는 것이 ETag와 If-None-Match이다.

ETag는 서버가 임의로 만든 값이다. 이 값은 주로 response body를 해싱하던가 버저닝을 통해 값을 정한다.

response가 stale해지면 ETag의 값을 If-None-Match 의 값을 ETag값으로 설정한 후, 서버로 보내서 validation을 진행하게 된다. 서버에서 현재 값과 비교 후에, 변한 것이 없다면 304(Not Modified)로 reponse가 올 것이고 캐싱정보를 갱신하게 된다.

캐싱 전략

캐시는 서버의 부하를 줄여주고 리소스 로드도 빠르게 해준다. 하지만 outdate한 정보나 원치 않는 정보의 캐싱이 일어날 수 있기 때문에 캐싱을 잘 사용해주어야 한다.

no-store에 대한 캐싱 전략

no-store는 캐싱하지 않는 방법이다. 이렇게 되면 항상 새로운 요청을 보내게 되고 새로운 정보를 항상 요청하게 된다. no-store를 사용하는 이유는 크게 3가지로 구분된다.

  • 개인적인 정보를 저장하고 싶지 않아서
  • 항상 최신정보를 불러와야해서
  • 캐싱을 해둔 정보가 어떤 여파를 미칠지 몰라서

하지만 위 경우에도 no-store 보다는 다른 캐싱전략을 사용하는 것이 좋다.

개인적인 정보를 캐싱하는 방법: private

개인적인 resource라면 private 을 이용하는 것이 좋다. 이를 설정하게 되면 해당 정보는 다른 클라이언트에는 캐싱되지 않고 오직 마지막 브라우저의 유저에게만 캐싱된다. 주로 로그인 정보를 캐싱해두는 쿠키를 사용할 때 private 을 사용하면 좋다.

항상 최신정보를 불러와야되는 경우: no-cache

no-cache 를 이용한는 것이 좋다. no-store를 이용하는 경우 기존에 저장된 캐쉬는 사라지게 할 방법이 없기 때문이다. 그래서 no-cache 를 통해 캐시의 유효성을 검사하고 새로운 캐시로 대체하는 것이 정보의 무결성을 보장하게 된다.

outdated한 구현의 정보를 다루자: no-cache

oudated한 정보를 다룰 때, 여러가지 옵션들(max-age=0, must-revalidation…)을 쓰는 것 보다 no-cache 하나로 해결할 수 있다.

변하지 않는 값을 활용

변하지 않는 리소스가 있다면 immutable 값을 이용하면 캐싱해두고 reload에 의해 갱신되지 않기 때문에 효율적이게 된다.

request Callapse

중간에 shared cache 서버를 둔다면 더 효율적으로 운영할 수 있다. 다수의 클라언트의 요청이 와도 CDN과 같은 서버에서 서버로 1회 요청을 보내어, 그 response를 다수의 클라이언트의 response로 보낼 수 있게된다. 이 와같은 방식을 request callapse라고 한다.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching/request-collapse.png

휴리스틱 캐싱보다 항상 캐싱을 명시하기

기본적으로 휴리스틱 캐싱이 일어나기 때문에 캐싱전략을 명시하는 것이 좋다.

자세한 전략들

서브 리소스들은 해싱이나 버저닝을 이름에 넣어서 URL을 경로자체를 식별자로 사용하는 것이 좋다.

JS, CSS 파일의 이름을 매번 버저닝이나 해싱을 통해 다르게 한다면 URL이 달라질 것이고 이는 해당 URL에 대한 캐싱을 최대한으로 둬도 새로운 버전이 업데이트 된다면 내용 또한 업데이트 시킬 수 있게 된다.

QPACK이용

HTTP3에서는 number를 통해 헤더 옵션들을 가볍게 설정할 수 있게 된다.

메인 리소스는 no-cache 전략을 사용하자(HTML)

main-resource는 항상 새로운 response가 필요하기 때문에 no-cache 를 이용하는 것이 좋다.

참고
https://toss.tech/article/smart-web-service-cache
https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching

profile
나무아래에 앉아, 코딩하는 개발자가 되고 싶은 박철현 블로그입니다.

0개의 댓글