티스토리 뷰
캐시 란?
캐시는 자주쓰이는 문서의 사본을 자동으로 보관하는 HTTP 장치다.
리소스 요청시의 문서의 사본이 존재하면 원 서버가 아니라 캐시로 부터 제공이 된다.
- 불필요한 데이터 요청을 줄인다. → 네트워크 요금 비용을 줄인다
- 병목현상을 해결한다 → 대역폭을 늘리지 않고 페이지를 빨리 불러온다.
- 원서버 요청을 줄여준다 → 서버의 부하를 줄이면서 더 빨리 response한다.
- 거리로 인한 지연을 줄여준다.
적중과 부적중
- 적중: 유효한 사본이 있을 경우 캐시적중이라고 하며 해당 사본으로 응답한다.
- 부적중: 유효한 사본이 없을 경우 원서버에 요청하여 새로운 사본을 받아 응답한다.
- 에러: 유효한 사본이 없을경우 원서버에 요청하는데 새로운 사본이 없을 경우 에러 발생
재검사
💡 신선도검사: 캐시의 경우 원서버의 데이터와 일치하는지 사본을 점검해야 한다.
- 콘텐츠가 변경되지 않을 경우 304 not modified 스테이터스 반환
- 신선한지의 여부를 어떻게 알 수 있을까? → IMS (if- modified-since) 헤더를 통해 재검사를 진행한다.
- 오늘날 적중률이 40프로만 되도 좋은편에 속한다. 캐시를 잘 활용하면 상당한 트래픽을 줄이고 더 빠른 응답을 기대할 수 있다.
적중과 부적중 구별
- Date 헤더: Date헤더를 이용해 단순 날짜 비교
- Age 헤더: 얼마나 오래 되었는지 파악할 수 있다. 초 단위 사용
캐시 토폴로지
캐시의 경우 전용캐시와 공용캐시로 나뉘며 이를 나누는 기준은 캐시를 공유하는지의 여부에 따라 나뉜다.
전용캐시
- 웹브라우저는 개인전용캐시를 내장하고 있다.
- 브라우저는 자주쓰이는 문서를 컴퓨터디스크와 메모리에 캐시해 놓는다.
프락시캐시
- 프락시를 이용하여 공용된 캐시를 사용한다.
- 깊게 다루진 않겠다.
캐시 처리단계
- 요청받기
- 파싱
- 검색
- 신선도 검사
- 응답 생성
- 발송
- 로깅
요청받기
클라이언트의 요청을 받아들여 트랜잭션처리를 실행한다.
파싱
헤더 부분을 조작하기 쉬운 자료구조에 담아 캐싱을 더 처리하기 쉽게 만들어준다.
검색
- URL을 알아내여 로컬 사본이 있는지 검사한다. (메모리나 디스크 확인)
- 사본에 없는 경우 원서버나 프락시에 요청
신선도 검사
- 먼저 정해진 기간이 지났는가? → 안 지났으면 신선하다.
- 정해진 기간이 지나면 재검사를 실행한다
- 재검사 시 기존 사본과 차이가 있는가> -? 차이가 있으면 새로운 사본을 보내준다.
- ETag 이용 시 기존 사본과의 차이 여부를 알 수 있다. 그래서 새로운 사본 대신 기존 사본을 이용할 수 있다.
- IMS 사용 시 기존 사본과의 차이 여부를 알 수 없어 무조건 새로운 사본을 보내준다
응답 생성
- 캐시된 서버 응답헤더를 토대로 응답헤더 생성
- Date 헤더 건드리지 말 것
- 신선도 정보 삽입 (cache control age expires)
전송
- 클라이언트에 돌려줌
로깅
- 캐시적중과 부적중 횟수에 대한 통계를 갱신한다
- 로그파일에 어떤 종류의 요청이 왔고 무슨일이 일어났는지를 기록한다.
유효기간과 나이
Cache-Control: max- age | - 초단위의 값이 들어간다. - 문서의 최대 나이를 정의하고 해당 초가 지나면 더이상 신선하지 않다고 판단한다. |
Expires | - 절대유효기간을 명시한다. - 명시한 기간을 넘어가면 신선하지 않다고 판단한다. |
서버 재검사
문서가 변경되었는지의 여부를 물어볼 필요가 있음을 의미한다.
- 콘텐츠가 변경되었을 경우 새로운 사본을 가져와 갱신한 후 클라이언트에게 보내준다.
- 콘텐츠가 변경되지 않았다면 새 만료일을 포함한 헤더들만 가져와서 캐시안의 헤더들만을 갱신한다
조건부 메소드와 재검사
캐시 재검사를 할 때 IMS와 INM 헤더를 이용한다.
If-Modified-Since : <date> | - 주어진 날 이후로 수정되었다면 요청 메소드를 처리한다. -Last Modified 응답헤더와 함께 사용한다. |
If-None-Match : <tagsa> | - 문서에 대한 일려번호와 같이 동작하는 Etag와 함께 사영한다. - Etag가 다를 경우에 문서를 갱신한다. |
약한검사기와 강한검사기
W/ 를 이용하여 약한검사기와 강한검사기를 구분한다.
약한검사기
- 콘텐츠가 조금 변경되더라도 ‘그정도면 같은것’(주석 등)이라고 서버가 주장할 수 있는 약한 검사기를 지원한다.
강한검사기
- 콘텐츠가 바뀔때마다 변경된다.
캐시 최적화 방법
- 캐시 최적화는 response header에 담아야 하는 것이기 때문에 웹서버에서 설정을 해주어야한다.
- aws에서는 cloudfront에서 설정하면 될 거같은데 좀 더 알아봐야 한다
캐시 종류
- no cache: 캐시를 사용하기 전에 서버에 먼저 검사 한다.
- no store: 캐시 사용x
- public: 모든환경에서 사용가능
- private: 서버에서 서버간으로 이동할 때 외부서버에서도 캐싱을 적용하는데 private로 하면 브라우저에서만 캐시가 가능하다
예를들어 개인정보에 민감한거나 공유가 되면 안되는 경우에 사용한다! - max-age: 캐시의 유효기간이며 초 단위이다.
ex)
cache-control: max-age=60
cache-control: private, max-age=600
cache-control: no-cache (=max-age=0)
리소스 별 효율적인 캐시 설정
💡 캐시는 항상 설정을 할 것, (단 리소스가 변경되지 않는다는 조건하에, 만약 리소스가 변경되는 경우엔 캐시를 적용하면 최신화가 되지 않는 문제가 발생할 수 있다.)
ex) 캐시의 기간이 1일 인경우
→ 이미지가 변경되었더라도 하루동안은 계속 똑같은 사진을 보내주게 됌, 문제점으로 변경사항이 발생해도 변경이 되었는지 클라이언트는 경험할 수 없음
HTML파일
- html이 만약 변경되었으나 캐시가 설정되어 있으면 변경사항이 발생해도 기간동안 변하지않는다. 실제로 회사에서 서비스를 만들었을 때 배포후에도 변경되지 않았다고 컴플레인이 들어오기도 했었다.
- no-store또는 no-cache를 사용한다. 상황에 맞게 선택해서 써야하지만 no-cache를 사용하면 변경사항이 없을 때 캐쉬를 사용할 수 있음으로 일반적인 경우에는 no-cache를 사용하는 것을 권장함JS파일
- 자바스크립트의 경우 webpack으로 번들링을 하는 과정에서 파일에 해쉬값이 붙어 새롭게 배포를 하게되면 항상 새로운 파일로 생성하게된다.
- 변경사항이 생기면 항상 새로운 파일로 생성이 되어 캐쉬값을 무한대로 걸어주어도 된다.
- 파일명 main.31a12.js → main.132wqq.js 같이 변경
- CSS파일
- 자바스크립트와 동일
- img 파일
- 변경되지 않는 이미지는 무한으로 걸어준다.
- 변경되는 이미지에는 해쉬값을 설정하며 자바스크립트파일처럼 변경되었을 때 최신데이터로 업데이트가 될 수 있게 해주는 것이 좋다
결론
html만 no-cache를 권장하고 js,css,img는 해쉬파일로 만들고 캐쉬를 최대한 길게 설정하는 것이 좋다.
html no-cache
js,css,img public,max-age=31536000(1y)
setHeaders: (res, path) => {
if (path.endsWith(.html)) {
res.setHeader('Cache-Control', 'no-cache')
} else if (path.endsWith(.js) || path.endsWith(.css) || path.endsWith(.webp)) {
res.setHeader('Cache-Control', 'public, max-age=3156000')
} else {
res.setHeader('Cache-Control', 'no-store')
}
}
출처
- http완벽가이드
- 웹 성능 최적화 by 유동균
- 웹 성능 최적화 기법
'프론트엔드' 카테고리의 다른 글
yarn berry로 monorepo 만들기 (2) | 2023.03.10 |
---|---|
브라우저 최적화 -Reflow, Repaint (0) | 2023.03.09 |
브라우저 렌더링 최적화 - LCP (0) | 2023.03.09 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 1600 파이썬
- 에러핸들링
- 선언적 UI
- nextjs 에러핸들링
- 불량 사용자 자바스크립트
- storybook scss import
- 백준 1600번
- React useCallback
- 미로탈출 명령어
- react suspense
- serverless 배포
- node version yarn berry
- nestjs 배포하기
- storybook scss이슈
- 백준 22862
- serverless nestjs
- nextjs errorboundary
- CSS
- suspense 장점
- 가장 긴 짝수 연속한 부분 수열
- javascript
- 관심사 분리하기
- storybook react is not defiend 해결
- 표현 가능한 이진트리
- 자바스크립트
- 서버사이드 error handling
- useCallback과 useMemo 사용
- node 버전 마이그레이션
- 서비스 디자인 패턴
- React useMemo
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함