https://velog.io/@leehyunho2001/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%BA%90%EC%8B%9C
https://velog.io/@jay/it-is-nothing-but-static-file-cache
https://toss.tech/article/smart-web-service-cache
서비스를 개발하던 도중, 이런 이슈가 있었다.
여느 때와 같이, 기능을 신규개발해서 운영계에 배포하던 후 였다. 분명히 개발계/스테이징계 에서 해당 기능이 제대로 동작했음을 검증을 하고 올렸다. 하지만, 배포 후 간헐적으로 몇몇의 사용자가 운영계에서 이거.. 안되는데요? 라는 이슈가 나온 것이다. 그외의 사용자들은 잘 동작했다.
왜이런 이슈가 발생했을까? 왜인지 설명하기 전에, 이 이상한 이슈의 원인부터 설명하자면 브라우저 캐시때문이다.
캐시(Cache) 그거시 뭔디
정의는 데이터나 값을 미리 복사해놓는 임시 장소를 가르킨다. 사실 이렇게 정의만 봐서는 잘 와닿지 않는다.
예를 들어보자. (정말 그냥 예시이다.)
사용자가 네이버를 접속한다고 해보자.
그럼 네이버의 웹서버는 네이버화면을 띄우기 위한 컨텐츠들을 서버에서 다운받아 사용자에게 뿌려줄 것이다.
여기서 만약, 사용자가 네이버화면을 아주 여러번, 과도하게 100000번 호출한다고 하면... 웹서버는 그럼 컨텐츠를 100000번 다운받아 사용자한테 뿌려줄까? 사용자가 한명이 아니라 몇백, 몇천명이 동시에 그런다면 서버는 어떻게 감당할까?
사실 예시를 정말 허무맹랑하게 들었지만, 실제로는 서버는 100000번 컨텐츠를 요청한다고해서 100000번 주지 않는다.
한 번 노출했을 때 그 컨텐츠를 특정 위치에 저장해두고, 그 다음 또 동일한 요청을 하면 서버까지 요청이 가지 않고 저장해둔 컨텐츠를 보여주는 것이다.
이때 저장해둔 장소를 캐시라고 하고, 이 행위를 캐싱한다고 한다. 그리고 이렇게 브라우저에서 행하는 캐싱은 웹캐시중 브라우저 캐시라고 부른다.
나는 Back단에 대해 전혀 모르는 프론트엔드 개발자로 브라우저 캐시만 설명하겠다. ㅎ
브라우저캐시
HTTP 캐시라고도 하고, 모든 HTTP 요청은 서버로 직접 요청이 가지 않고 브라우저 캐시로 라우팅되는데, HTTP 캐시 내에 필요한 데이터가 존재하다면 캐시된 데이터를 반환한다.
그래서 어떻게 동작하는 데?
사용자가 첫 요청을 보내면,
1. 브라우저는 서버에 Index.html 파일을 요청한다.
2. 서버는 Index.html 파일을 찾아보고 존재하는 파일이면 파일 내용을 브라우저에게 header 값과 함께 응답한다.
3. 브라우저는 응답받은 내용을 브라우저에 표시하고, 받은 header 에 따라 캐쉬 정책을 수행한다.
브라우저 캐싱
그럼 다시 본론으로 돌아오자면,
웹브라우저로 사용자가 접속해서 요청한 값이 브라우저에 캐싱된다는 것이다.
번들
웹이 배포가 이루어지면, 웹의 모든 리소스는 번들로 묶여서 제공된다. 번들에는 애플리케이션 실행을 위해 모든 코드를 포함하고 있게 된다.
우리는 일반적으로 `webpack`, `parcel`, `rollup` 과 같은 번들러를 사용하여 번들링을 하는 것이다.
하지만, 이때 번들 파일의 내용이 변경될 때 마다 새로운 해시값을 생성하도록 설정해야 한다.
만약 번들의 해시를 사용하지 않는다면....?
개발자는 운영 배포를 할 때 마다, 유저가 최신버전의 애플리케이션을 이용할 것이라 기대한다. 하지만 유저는 나의 애플리케이션에 방문해도 과거버전을 이용할 수 있게 된다. 그 이유는 번들과 HTTP 캐시 때문이다.
위에서 언급했듯이, 배포시 웹 애플리케이션의 모든 리소스를 번들링한다. 하지만 번들의 해시를 사용하지 않으면, 번들 파일 안의 내용은 변경될지라도 번들 파일 이름들은 같다.
module.exports = {
output: {
filename: 'bundle.[contenthash].js',
},
// ...
};
예를들어, 브라우저가 `bundle.js` 라는 파일을 캐시한 후에, 웹이 새로 배포되어 `bundle.js` 안의 내용이 변경되더라도 해시값이 없으면 동일한 파일로 인식하여 캐시된 번들 파일을 사용하는 것이다.
그래서 번들의 해시를 이용하여 브라우저가 변경된 파일을 인식하고 다시 리소스를 다운로드 하도록 유도하는 것이다.
캐시무효화
브라우저가 캐시된 자원이 수정되었는지 확인할 수 있도록 하는 것을 캐시 무효화라고 한다. 번들의 해시를 이용하지 않더라도, 캐시 무효화를 할 수 있는 방법들도 존재한다.
Cache-Control Header 를 명확하게 사용하는 것이다. HTTP 응답 헤더에 Cache-Control 헤더를 추가하여 브라우저에서 캐시를 어떻게 사용할 지 명시할 수 있다.
예를들어, Cache-Control:no-cache 를 사용하면 브라우저가 캐시된 리소스를 사용하지 않고 항상 서버에서 새로운 리소스를 가져온다.
이런 부분들을 잘 설계하면 가능할 것이다. (더 자세히는 잘 모르겠다.)
사실..
이런저런 방법을 이용해서 배포할 때 마다 최신서비스를 이용할 수 있다. 사용자가 웹에 들어오거나 새로고침을 할 경우에만 말이다.
만약 사용자가 웹사이트에 접속된 상태에서 서비스를 이용하다가 배포를 해버리면, 사용자는 새로고침을 하지 않는 이상 과거의 사이트에 머물러 있는 것이다.
이와같은 경우 새로운 배포가 발생할 시 새로고침을 유도하는 메세지를 띄우는 것이다. (되겠냐고...)
'🌳Frontend > etc' 카테고리의 다른 글
포커스된 요소의 부모요소에 스타일링 (2) | 2023.06.15 |
---|---|
[브라우저] 버블링과 캡처링 (0) | 2023.06.07 |
캐시(Cache) 제어 Header 종류 (0) | 2023.05.26 |
인증과 사용자 세션 1 (0) | 2023.04.25 |
CSS-in-CSS vs CSS-in-JS (0) | 2023.04.13 |