안녕하세요. 프론트엔드 개발자 진돌입니다.
클라이언트 개발자가 다루게 되는 캐시는 서버 상태 캐시외에 http private 캐시(브라우저 캐시 등), http public 캐시(CDN 등)이 있습니다.
오늘은 해당 내용들을 정리하는 글을 작성해보겠습니다.
http header를 통한 cache
http 리소스의 cache는 Cache-Control header 통해서 하게되며, 캐시가 되는 위치에 따라 크게 public cache, _private cache_가 있습니다. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
private cache
private cache는 클라이언트 캐시라고도 말하며, 말그대로 클라이언트 어플리케이션에서 http 응답 header 값을 이용하여 캐시를 합니다. 웹브라우저에서는 해당 값에 따라 메모리나 디스크에 캐시를 하게됩니다.
캐시 유효 기간 설정
Cache-Control max-age=(seconds)
값을 통하여 리소스의 캐시 시간을 정할 수 있습니다. 해당 캐시가 있는 동안에는 브라우저에서 캐시된 데이터를 가져오게 됩니다.


위 이미지는 실제 유튜브에서 노출되고 있는 영상의 썸네일 이미지의 http 통신 데이터입니다.
아래 이미지에 디스크 캐시에서 가져온다고 적혀있는 것처럼 max-age 값에 7200초 동안에는 해당 이미지를 디스크 캐시에서 가져오게 됩니다.
해당 캐시시간이 만료되기 전까지는 서버에서 아무리 값이 바뀌어도 유효한 캐시를 지울 수는 없어서 신중히 설정해야 합니다.
캐시 재검증
캐시가 만료가 되었다고 똑같은 데이터를 그대로 가져온다면 상당히 비효율적입니다. 데이터 재검증을 위한 http header도 존재하고, 해당 검증에 따라서 캐시 데이터를 사용할지 서버에서 새로 데이터를 가져올지 결정합니다. 재검증을 위한 http header도 존재하는데 아래와 같습니다.
- Last-Modified 데이터의 최종 수정 시각을 명시하여, 시간이 지나지 않은 경우는 response body는 주지 않고 304로 캐시 되어있는 데이터를 사용하라고 명시함
- ETag 데이터의 임의의 Tag값을 주어서, Tag값이 변했는지의 여부에 따라 response body는 주지 않고 304로 캐시 되어있는 데이터를 사용하라고 명시함
이렇게 했을 경우 이미지같은 데이터는 용량이 클텐데 header값만 주게 되어 빠르고 적은 데이터만을 통신하여 캐시 데이터를 사용할 수 있게 됩니다.
public cache
public cache는 CDN, cloud-front같이 프록시 서버에서 캐시하는 것을 말합니다. 프록시 서버에서 캐시가 되면 해당 캐시값은 모든 해당 리소스를 요청하는 클라이언트에게 적용이 됩니다.
React cache
react application에서도 마찬가지로 기본적인 http 헤더를 통해 웹브라우저가 핸들링하는 캐시를 사용합니다. 거기에 더해서 요즘에는 필수적으로 사용하는 Tanstack(react-query), SWR 같은 서버상태관리 라이브러리를 통해서도 캐시를 관리합니다.
둘다 캐시 데이터여서 조금 혼란이 있을 수 있는데 사용되는 용도가 조금 다릅니다.
서버 상태 관리 라이브러리
클라이언트가 주체로 서버 상태 관리하기 위한 라이브러리입니다. 주문 리스트, 유저 정보 리스트 등 데이터 자체를 캐시하고 있어서 해당 캐시를 다시 받아올지를 클라이언트가 결정하게 됩니다. 이미지 등 바이너리 데이터를 캐시하는게 아니라 이미지를 가져오기 위한 url에 대한 데이터를 캐시하는 용도로 사용하게 됩니다.
http cache
서버가 주체로 캐시를 관리하게 됩니다. 서버의 http response header에 따라서 브라우저 등에서 캐시를 관리하게 됩니다. 데이터 상태를 캐시하는게 아니라 파일 자체를 캐시하는 용도로 사용합니다. ex) html, js, image 등
React Native cache
React와 개념자체는 비슷하게 캐시를 하게 됩니다. 다른 점은 브라우저 환경이 아니기 때문에 http cache를 자동으로 제공해주고 있지 않습니다.
그렇다고 private cache를 하지 않아도 되는걸까요?
public만 사용하면?
결론부터 말하면 public cache만 사용하면 비용이나 사용성에서 좋지 않습니다.
CDN 등에 있는 캐시만을 사용할 경우에는 CDN 서버 자체에 캐시된 데이터를 가져오는 http 요청을 하게 됩니다. 캐시된 데이터를 가져오지만 캐시된 데이터를 가져오는 http 요청은 반복되게 됩니다. 애플리케이션단에서 이미지를 보여줄 때마다 요청하게 이미지가 뜨는 속도, 비용 모두 좋지 않습니다.
private cache 함께 사용하면
CDN에 있는 데이터를 애플리케이션에서 캐시를 하고 사용하게 됩니다. 누군가 이미 요청을 해서 public cache를 해놨다면 해당 캐시된 데이터를 빠르게 가져올 것입니다. 다음으로는 애플리케이션에 캐시를 하였고 다시 앱에서 이미지를 사용할 때는 더욱 빠른 이미지를 보게 됩니다.
결론
private cache와 public cache모두 필요하고 이를 위해서는 직접 응답값에 따른 async storage를 사용한 로컬 캐시를 구현해야 합니다. 해당 캐시를 위한 다양한 라이브러리가 있기에 해당 라이브러리들을 사용하여 private cache와 public cache를 모두 해줘야 합니다.
마무리
react나 reactnative에서 public(client), private(CDN), 서버상태라이브러리들의 사용 용도에 대해서 정리해보았습니다.
감사합니다.
