티스토리 뷰

캐시의 cs적인 부분으로 들어가면 시간적 지역성, 공간적 지역성, 파레토 법칙 등의 개념이 나오는데

오늘은 프론트엔드 개발자가 캐시를 어떻게 하면 조금 더 섬세하게 다룰 수 있는지 알아보고

그 와중에 클라우드프론트(CDN)의 역할은 무엇인지 알아보자.

 

캐시는 웹의 성능을 높이기 위해 사용된다.

단, 잘못 관리하면 원하는 시점에 캐시가 사라지지 않아서 업데이트된 파일을 보여주지 못할 수도 있고

필요 이상의 http요청이 발생하기도 한다. 

그래서 캐시와 관련된 여러 기능을 알아두고 섬세하게 조절하는 것이 필요하다.

 

일단 각 개념과 기능을 알아보고 

토스에서는 이를 어떻게 활용하는지 배움으로써 맛보기를 해보자

 

캐시가 없을 때

브라우저에서 http요청을 보내고 오리진 서버는 html, css, js, 이미지 등 정적 파일(리소스)을 응답한다.

완전한 요청과 완전한 응답이다.

이때 http응답에 포함된 Cache-Control 헤더에 따라 리소스의 생명주기가 결정된다.

max-age의 값으로 유효한 시간(초)을 지정해준다.

 

위 리소스의 생명은 31536000초(1년)이다.

1년이라는 유효기간이 지나기 전에는 이 브라우저는 이제 서버에 요청을 보내지 않고 캐시를 읽어와서 사용한다.

위 리소스는 메모리에서 읽어왔다.

 

그럼 1년이 지나면 캐시가 완전히 사라지고 다시 완전한 http요청을 보낼까?

아니다. 효율적으로 한다.

방금까지 가지고 있었던 캐시가 아직까지 유효한지 재검증(Revalidation)을 한다.

만약 파일이 아직도 그대로라서 캐시가 유효하다면

304 Not Modified response를 보낸다.

네트워크 탭에서 304 요청을 눌러보면 Size와 Time이 있긴 있지만 매우 적다.

http본문을 포함한 응답이 아니라 유효함의 여부만 확인해서 응답하기 때문에 큰 용량이 필요하지 않다.

 

재검증 방법은 ETag와 마지막 수정시간을 이용한다.

모든 데이터는 데이터를 해시한 형태의 ETag를 가지고 있다. 만약 파일의 데이터가 변하면(수정이 되면)

당연히 데이터 해시값도 바뀐다. ETag가 바뀐다.

브라우저는 http요청을 보낼 때 헤더에 If-None-Match에 현재 ETag값을 담아서 보낸다.

그리고 응답의 ETag가 이것과 같다면 파일이 수정되지 않아서 아직 유효하다는 뜻이므로 304를 보내준다.

응답의 ETag가 이것과 다르다면 파일이 수정되었다는 뜻이므로 200 응답을 보내면서 새 파일을 보내준다.

If-Modified-Since는 캐시 된 리소스의 Last-Modified값 이후에 서버의 리소스가 수정되었는지 확인한다.

 

 

max-age = 0 이란?

캐시를 저장하지 않는다는 말이 아니다.

캐시를 저장했지만 그 유효시간이 0초라는 뜻이다. 즉, 매번 재검증 요청을 보내서 확인한다는 뜻이다.

파일이 바뀌지 않으면 304를 보내서 약간의 시간과 약간의 용량이 필요할 것이다.

하지만 매번 재검증을 하니 파일의 변경이 있는 경우 지체 없이 새 파일을 받아올 수 있을 것이다.

 

no-cache와 no-store

no-cache: max-age=0과 동일한 뜻을 가진다. 캐시는 저장하지만 매 요청마다 재검증을 요청한다.

no-store: 캐시를 아예 사용하지 않는다. 캐시를 만들지도 마라. 라는 강력한 값

 

 

캐시의 위치

 

이쯤에서 혼동이 된다. 클라우드프론트의 캐시랑 브라우저 캐시랑 똑같은 건가?

내가 클라우드프론트에서 지정했던 TTL이 브라우저 캐시의 시간인가?

엣지로케이션의 캐시 유효시간인가? 

내가 CloudFront에서 지정했던 TTL은 엣지로케이션의 캐시 유효시간이다. 

클라우드 프론트를 사용하는 이유

내 오리진 서버가 미국에 있다.

서울의 유저가 리소스를 요청하면 클라우드 프론트는 일단 가장 가까운 엣지로케이션으로 연결한다.

첫 요청이니 엣지로케이션에도 캐시가 없다. 오리진서버와 통신해서 유저가 요청한 리소스를 가져온다.

그럼 그 리소스를 유저에게 전달한 후에 자신의 엣지로케이션에 캐시를 저장한다.

두 번째 서울의 유저가 들어오면 방금 그 엣지로케이션에 연결이 된다. 아까 오리진에서 받았던 리소스를 캐시 해 두었다.

오리진에 요청을 보낼 필요 없이 엣지로케이션에서 바로 응답을 해준다.

오리진 서버와 통신이 줄어들고 서울과 가까운 엣지로케이션에서 바로 응답을 해주니 더 빠르다.

 

이 상황이 되면 캐시가 여러 곳에 생긴다. 즉, 세심히 다뤄야 할 필요가 생겼다.

 

일반적으로 캐시를 없애기 위해 CloudFront에서 무효화를 진행하는데, 이것은 CDN 즉 엣지로케이션의 캐시를 삭제한다는 뜻이다.

우리의 유저는 이미 브라우저에 캐시를 가지고 있기 때문에 CDN 캐시를 삭제한다고 해서 브라우저 캐시까지 삭제되지는 않는다.

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

 

Cache-Control: public과 private

Cache-Control의 헤더 값으로 pubilc과 private를 추가할 수 있다.

public: 모든 브라우저와 엣지로케이션이 캐시를 저장할 수 있다.

private: 브라우저만 캐시를 저장할 수 있다.

 

s-maxage

엣지로케이션만 적용되는 max-age값을 설정한다. 

예를 들어 s-maxage= 31536000, max-age=0으로 설정하면

엣지로케이션에는 1년 동안 유지되지만 브라우저는 매번 재검증 요청을 보낸다.

 

 

토스에서 캐시 다루는 방법을 배워보자

1.

예를 들어 새로 배포가 이루어질 때마다 데이터가 바뀌는 html리소스의 경우, 브라우저는 항상 새로운 배포를 확인해야 함.

(자주 바뀌니까 매번 확인해야지. 그렇다고 캐시를 안 쓰는 건 너무 비효율적이니까)

이런 경우 토스는  Cache-Control 값으로 max-age=0, s-maxage=31536000 을 설정한다.

해석해보자면 CDN엣지로케이션에는 1년 동안 유지하고 브라우저는 매 요청마다 재검증을 하라는 뜻.

아마 토스는 무중단배포 시 CDN 무효화를 같이 진행할 것이다. 

이렇게 되면 CDN 캐시 서버는 배포 때마다 새로운 파일을 캐시 하게 될 것이고

브라우저는 매번 재검증을 요청하므로 304를 주로 받게 되고 혹은 200을 받게 될 것이다.

304도 충분히 빠르다.

 

2.

토스는 임의의 버전 번호를 URL앞에 붙여서 빌드 결과물마다 고유한 URL을 가지도록 설정한다고 한다.

즉 JS, CSS 파일이 URL에 대해 내용이 바뀌는 경우는 없다는 뜻이다.

URL이 바뀐다? JS, CSS도 바뀐다 는 뜻이기 때문에 캐시가 만료될 일도 없다.

이런 경우 무조건 최대치로 설정해서 max-age: 31536000으로 1년간 유지시킨다.

배포가 일어나지 않는 한 브라우저는 캐시를 사용한다.

 

 

 

 

 

캐시 개념이 CDN과 합쳐지면서 조금 혼란스러웠는데 잘 정리해주신 박서진 님께 다시 한번 감사합니다.

수많은 공식문서와 블로그 등 자료를 읽었지만 토스의 박서진 님이 작성하신 문서에서 많은 것을 정리할 수 있었습니다.

https://toss.tech/article/smart-web-service-cache

 

웹 서비스 캐시 똑똑하게 다루기

웹 성능을 위해 꼭 필요한 캐시, 제대로 설정하기 쉽지 않습니다. 토스 프론트엔드 챕터에서 올바르게 캐시를 설정하기 위한 노하우를 공유합니다.

toss.tech

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함