Spring Boot와 Vue로 구성된 프로젝트에서 서버 요청이 많아 브라우저 속도가 느려지는 문제가 생겼다.
반복되는 요청을 최소화하고 성능 개선을 위해 캐시를 선택했고, 먼저 클라이언트에 캐싱할지 서버에 캐싱할지 선택했다.
[ 캐싱의 장점 ]
더보기
- 응답 시간 단축:
- 자주 요청되는 데이터를 빠르게 제공
- 사용자 경험 향상
- 서버 부하 감소:
- 반복적인 연산과 데이터베이스 쿼리 감소
- 서버 리소스 절약
- 네트워크 트래픽 감소:
- 불필요한 데이터 전송 최소화
- 대역폭 사용 효율화
- 확장성 개선:
- 동일한 하드웨어로 더 많은 요청 처리 가능
- 비용 효율적인 성능 향상
- 가용성 향상:
- 서버 장애 시에도 캐시된 데이터로 부분적 서비스 제공 가능
- 일관된 성능:
- 트래픽 급증 시에도 안정적인 응답 시간 유지
캐싱을 효과적으로 구현하기 위한 몇 가지 팁:
- 캐시 계층 다양화:
- 브라우저 캐시, CDN, 애플리케이션 서버 캐시, 데이터베이스 캐시 등 다층적 접근
- 캐시 무효화 전략:
- 데이터 변경 시 관련 캐시를 적절히 갱신하는 메커니즘 구현
- 캐시 수명 최적화:
- 데이터의 성격에 따라 적절한 TTL(Time To Live) 설정
- 캐시 키 설계:
- 효율적인 캐시 히트를 위한 적절한 캐시 키 구조 설계
- 모니터링 및 분석:
- 캐시 히트율, 미스율 등을 모니터링하여 지속적인 최적화
- 부분 캐싱:
- 전체 페이지가 아닌 동적 컴포넌트만 별도로 캐싱
- 사용자별 캐싱:
- 개인화된 콘텐츠에 대한 사용자별 캐싱 전략 수립
선택지는
클라이언트 캐싱 방법
- 전역 상태 관리 (Vuex, Pinia 등)
- 브라우저 캐시 (HTTP 헤더 Cache-Control)
- LocalStorage/SessionStorage 사용
- 클라이언트 저장소 추가 (IndexedDB, Service Workers)
더보기
- 전역 상태 관리 (Vuex, Pinia 등)
- 장점: Vue.js 애플리케이션에서 전역 상태 관리 도구(Vuex, Pinia 등)를 사용하여 게시판 데이터를 관리합니다. 데이터가 전역 상태에 저장되어 재요청 없이 페이지 간 데이터 공유가 가능합니다.
- 단점: 대규모 데이터(예: 전체 게시판 글 목록)를 전역 상태로 관리하면 메모리 사용량이 늘고, 상태 관리가 복잡해질 수 있습니다.
- 적용 상황: 로그인 상태, 사용자 프로필, 중요한 소수의 데이터뿐만 아니라 자주 변하지 않는 게시판 데이터를 임시로 관리할 때 유용합니다.
- 브라우저 캐시 (HTTP 헤더 Cache-Control)
- 장점: 브라우저에서 서버의 응답을 캐시하여 네트워크 요청 없이 빠르게 데이터를 제공합니다. 서버 측에서 캐시 제어가 가능해 유효 기간을 쉽게 설정할 수 있습니다.
- 단점: 캐시된 데이터가 유효 기간 동안 새로고침되지 않으며, 특정 조건(로그아웃, 사용자 전환 등)에서 관리가 어렵습니다.
- 적용 상황: 게시판처럼 읽기 전용의 빈번한 요청에 적합하며, 새로고침 주기가 긴 데이터에 적합합니다.
- LocalStorage/SessionStorage 사용
- 장점: 클라이언트에서 데이터를 로컬에 저장하여 빠르게 접근할 수 있습니다. 브라우저를 닫아도 데이터가 유지되며, 비동기 요청 없이 사용 가능합니다.
- 단점: 데이터가 오래되면 직접 제거하거나 갱신해야 합니다. 대용량 데이터 저장에 비효율적이며, 보안이 중요한 데이터에는 적합하지 않습니다.
- 적용 상황: 브라우저가 꺼져도 유지되어야 하는 게시판 데이터나 비휘발성 데이터에 적합합니다.
- 클라이언트 저장소 추가 (IndexedDB, Service Workers)
- 장점: 대용량 데이터를 효율적으로 저장하고 관리할 수 있습니다. IndexedDB는 비동기 데이터베이스로 구조화된 데이터를 저장하는 데 유리하며, Service Workers는 오프라인 캐싱 및 데이터 동기화에 유용합니다.
- 단점: 구현이 복잡하고, 브라우저 호환성 문제가 있을 수 있습니다.
- 적용 상황: 게시판처럼 대량의 데이터를 저장하고자 할 때, 오프라인 모드를 지원하거나 빠른 데이터 접근이 필요한 경우.
- 기타 방법
- In-memory caching: 메모리에서만 데이터 저장, 탭 간 데이터 공유는 어렵지만 가장 빠른 접근 가능.
- APIs 요청 제한 및 Pagination: 데이터를 부분적으로 요청하여 캐싱 부담 줄이기.
선택 기준
- 데이터의 민감도: 개인 정보나 보안이 중요한 데이터는 브라우저 저장소보다는 안전한 방법으로 관리해야 합니다.
- 변경 빈도: 데이터가 자주 변경되지 않거나 변경이 즉시 반영될 필요가 없는 경우 브라우저 캐시가 효과적입니다.
- 데이터 크기: 대용량 데이터를 다룰 때는 IndexedDB나 Service Workers를 통한 캐싱이 적합합니다.
- 새로고침 주기: 사용자가 최신 데이터를 자주 확인해야 한다면, 전역 상태 관리나 로컬 스토리지의 적절한 사용을 고려해야 합니다.
정도가 있었는데
그중 브라우저 캐시와 세션 스토리지를 고려했다.
- 브라우저 캐시 (Cache-Control)는 서버가 클라이언트의 캐싱을 제어하여 빠른 응답을 제공하지만, 데이터의 최신성을 보장하기 위해 캐시 정책을 신중히 설정해야 함. 서버가 캐싱 지침을 제공하고, 브라우저가 이를 따르며 데이터는 메모리 또는 디스크에 저장됨.
- SessionStorage는 특정 세션 동안 데이터를 저장하며, 데이터의 일관성과 유효성을 관리하기 위해 타임스탬프와 같은 검증 로직을 함께 사용하는 것이 일반적임.
더보기
LocalStorage / SessionStorage
LocalStorage와 SessionStorage는 브라우저에서 클라이언트 측 데이터를 저장하기 위한 API로, 자바스크립트를 통해 데이터를 영구적으로 저장 가능
차이점
- LocalStorage: 브라우저를 닫아도 데이터가 유지됨. 사용자가 다시 브라우저를 열 때도 데이터를 사용할 수 있음
- SessionStorage: 브라우저 탭을 닫으면 데이터가 사라짐. 세션이 유지되는 동안만 데이터를 저장함
주요 메소드
- setItem(key, value): 데이터를 저장
- getItem(key): 데이터를 가져옴
- removeItem(key): 데이터를 삭제
- clear(): 모든 데이터를 삭제
장점
- 영구적 저장 (LocalStorage): 데이터를 지속적으로 저장하여 브라우저를 닫아도 유지할 수 있음
- 빠른 접근: 네트워크 요청 없이 저장된 데이터를 바로 사용할 수 있어 성능이 향상
단점
- 데이터 일관성 문제: 데이터가 변경될 때 수동으로 갱신해야 하며, 오래된 데이터가 남아 있을 수 있음
- 보안 이슈: 민감한 데이터를 저장할 때는 위험할 수 있으므로 주의가 필요함
- 저장 용량 제한: 일반적으로 LocalStorage는 약 5MB의 저장 용량 제한이 있음
브라우저 캐시 (HTTP Header Cache-Control) 작동 방식
- 서버가 응답할 때 Cache-Control 헤더를 설정하여 클라이언트에게 응답을 얼마나 오랫동안 캐시할지 알려줌
- max-age=<seconds>: 리소스가 신선하다고 간주되는 최대 시간(초)
- no-cache: 매번 서버에 리소스의 유효성을 확인
- no-store: 어떤 형태로든 캐싱하지 않음
- private: 브라우저만 캐싱 가능 (중간 캐시 서버는 불가)
- public: 모든 캐시에서 저장 가능
- 예: Cache-Control: public, max-age=300 → 서버가 브라우저에 300초(5분) 동안 응답을 캐시하라고 지시.
- 브라우저는 이 지시를 따르고, 지정된 시간 동안 서버에 다시 요청하지 않고 캐시된 데이터를 사용
캐시된 데이터는 어디에 저장될까?
- 브라우저의 메모리와 디스크에 저장됨
- 메모리 캐시: 브라우저가 실행 중일 때 메모리에 저장되며, 브라우저를 닫으면 사라짐. 빠른 접근 속도를 제공하지만, 휘발성임
- 디스크 캐시: 브라우저의 로컬 디스크에 저장되어 브라우저를 닫아도 남아 있음. 주로 더 오래 저장해야 할 경우 사용되며, 브라우저가 알아서 메모리와 디스크 간에 저장 위치를 결정함
- 캐시 위치와 유효성은 브라우저 개발자 도구에서 네트워크 탭을 통해 확인할 수 있음. 요청을 보면 from disk cache, from memory cache 같은 표시로 캐시된 데이터를 사용하는지 알 수 있음
'Spring Boot' 카테고리의 다른 글
JSON_ARRAYAGG & @JsonRawValue (1) | 2024.09.24 |
---|---|
AOP를 활용한 브라우저 캐시_4 정적 리소스 캐싱 명시 (0) | 2024.09.11 |
AOP를 활용한 브라우저 캐시_3_AOP / @GetMapping (2) | 2024.09.10 |
AOP를 활용한 브라우저 캐시_2_ETag & 인터셉터 (실패) (0) | 2024.09.10 |
Controller Annotation (0) | 2024.09.04 |