: 이부분은 http 관련한 설정으로 이뤄지는 파트이다. 사실 캐시 최적화 같은 경우에는 과거 이미지 사이즈 최적화와 유사하게 백엔드 쪽에서 해줄 작업이긴 하다. 애초에 브라우저에서 캐싱이란
이렇게 두가지로 나뉘는데, 브라우저 단에서 알아서
처리를 하기 때문에 개발자가 어떻게 컨트롤 할 수 없는 영역이긴 하다(물론 다른 캐싱과 웹개발을 두고 보면 다른 방법들이 있긴하다).
: 사람들도 쓸데없는 반복을 싫어한다. 어제 공부하고 완벽히 숙지했다고 생각되는 부분이 있을때(물론 불가능하지만,,) 다음날 그부분을 또 가르치고, 그 다음날 그 부분을 또 가르친다면 어떨까?. 비싼 돈 주고 쓸데없는 시간을 보내고 있다고 생각이 들 수 있다. 이렇듯 캐싱 또한 서버로부터 브라우저가 데이터를 받아올 때 이미 브라우저에서 다운을 받았던 것과 똑같은
것을 또 보내준다면 이러한 동일 파일의 다운로드는 일종의 리소스 낭비가 될 것이다. 이에 따라 이러한 낭비를 막기 위해 지난번 데이터와 같은 데이터를 다운받으려고 하는 경우 지난번 데이터와 동일한 경우에는 지난번에 다운받아놨던 것을 쓰는(다시 다운을 받지 않는) 것이 더 효율적일 것이다.
: 위에서 말한 것처럼 캐싱은 브라우저가 디스크 캐시, 메모리 캐시 중 선택하여(혹은 비율적으로 나눠서) 알아서 처리를 하는 것이고, 개발자 선에서 할 수 있는건 특정 데이터에 대해서 캐싱을 할지 말지 그리고 캐싱을 한다면 어느 정도 기간동안 캐싱을 할 것인지 등이다.
이에 따라 백엔드에서 response header
에 Cache-Control
세팅을 해줘야 한다. 아래는 Cache-Control
의 구체적인 옵션들이다.
프론트 - 백엔드
사이에 api를 보내고, response를 돌려주고 하는식으로 소통하는데 중간에, 예를 들어, CDN 등이 끼게 되면 다양한 중간 매개자가 생기게 된다. 이 때, 캐시를 사용하냐의 측면에서 중간의 CDN 등이 다른 매개체에도 캐시를 허용할거면 public을 옵션으로 해준다.그래서 실제 백엔드에서 header에 Cache-Control을 세팅해줄 때 아래와 같은 방법으로 한다.
Cache-Control : private, max-age=60
이 때,
Cache-Control : public, max-age=0
위와 같이 해주면 모든 서버에서(public) 캐시의 유효기간을 0초(초단위로 입력한다)로 세팅하는 것으로, 결과적으로 매번 현재 캐싱된 데이터가 최신인지 체크하도록 하는 옵션이다. 즉, 위의 no-cache
옵션과 결과적으로 같은 로직이다(캐시를 사용하기 전에 서버에 검사후에 사용하는 것).
const header = {
setHeaders: (res, path) => {
res.setHeader('Cache-Control', 'max-age=10');
}
}
NODEJS를 백엔드로 쓴다고 했을 때 위에 처럼 header 세팅에 cache-control을 세팅해줄 수 있다.
이 때, 보통은 HTML에 대한 캐시 옵션으로
res.setHeader('Cache-Control', 'no-cache');
를 써준다. html 의 경우 SPA인 리액트로 치면 핵심이 되는 로직이 모두 들어가 있기 때문에(js, css에 로직이 들어있다 했을 때 결국 이 js, css도 html에서 load한다), 매번 서버에 최신인지를 체킹해줘야한다. 하지만, 방금 말한 js, css 등은 변경 사항이 생기면 build를 할 때 unique한 이름으로 갱신이 되기 때문에(파일명 자체가 바뀜) html만 no-cache로 해뒀다면 load하는 파일명 자체가 바뀌기에 따로 최신인지를 체크할 필요가 없다. 그래서 js, css는 캐시의 유효기간을 무한정을 해놔도 상관이 없다.
res.setHeader('Cache-Control', 'public, max-age=31536000');
그리고 그 외에 파일들(캐시를 적용하지 않을 것들)에 대해서는 no-store를 써준다
res.setHeader('Cache-Control', 'no-store');
결론적으로 위에서 구두로 말한 내용을 간략하게 코딩해보면 아래와 같다.
const header = {
setHeaders: (res, path) => {
if (path.endsWith(".html")) {
res.setHeader("Cache-Control", "no-cache");
} else if (
path.endsWith(".js") ||
path.endsWith(".css")
) {
res.setHeader("Cache-Control", "public, max-age=3153600");
} else {
res.setHeader("Cache-Control", "no-store");
}
},
};
: ngnix 등으로 fe 빌드 파일을 배포할 때 위와 같은 캐시 컨트롤을 해주면 초기 로딩 속도 최적화를 할 수 있다. 물론 처음 홈페이지를 방문할 경우에는 캐시된 내용이 없겠지만 말이다.