- 운영 중인 서비스 로직은 서버로부터 새로운 리소스를 받으면 항상 고정된 경로의 로컬 파일 Storage 경로로 저장을 하고, Glide로 해당 이미지 리소스를 렌더링 하고 있었다.
- 그런데 어느날 서버로부터 변경된 리소스를 내려받아도 렌더링 단계에서 해당 리소스가 갱신되지 않는 문제를 발견.
- 분명히 로컬 저장 단계까지 변경된 리소스가 저장되는 것까지 확인했으나 원인은 Glide 동작 설정에 있었다.
- Glide는 기본적으로 캐싱 기능을 가진다. 디스크 캐시와 메모리 캐시를 활용하여 이미지를 빠르게 로드하고 불필요한 네트워크 요청을 줄이는 기능을 가지고 있다.
1. 메모리 캐시 (Memory Cache)
- 이미 로드된 이미지를 RAM에 저장하여 빠르게 다시 불러올 수 있도록 함
- 앱이 종료되거나 메모리가 부족하면 캐시가 사라짐
- 같은 이미지 요청 시 네트워크 요청 없이 빠르게 표시 가능
2. 디스크 캐시 (Disk Cache)
- 다운로드한 이미지를 저장소(파일 시스템)에 저장하여 다음에 로드할 때 재사용
- 기본적으로 이미지 원본(URL, 파일 등) 기준으로 캐시를 관리
(즉, 같은 URL이면 캐시 된 이미지 사용)
- 발견한 문제 상황은 로컬 저장소에 새롭게 저장했음에도 직전 리소스를 렌더링 하는 것으로 보아 디스크 캐시와 관련된 문제이다.
- 아래와 같이 단순히 선언한 경우에는 기본적은 캐싱 기능을 사용한다고 보면 된다.
Glide.with(context)
.load(imageUrl)
.into(imageView)
- 하지만 글 상단의 이슈처럼 문제가 될 경우에는 여러가지 캐싱 전략을 선택해야 한다.
- 먼저 기존 코드를 살펴보니 아래와 같았다.
Glide.with(context).load(File("${context.filesDir.absolutePath}/$param"))
.apply(RequestOptions().signature(ObjectKey(key))
.into(imageView)
- signature 메서드는 캐시 갱신 기준이 되는 키를 하나 정해 해당 값이 변경되는 기준으로 무조건 새로운 값을 호출하는 역할을 한다.
- 그런데 이 키 값이 공교롭게도 서버에서 중복되어 있었다. 따라서 새로운 리소스가 내려와도 키 값이 같아서 Glide 입장에선 절약을 위해 캐싱 데이터를 반환하던 것.
- 먼저 key를 시간 값으로 변경해서 매번 반드시 새로운 값을 반환하도록 수정할 수 있다.
Glide.with(context)
.load(File("${context.filesDir.absolutePath}/$param"))
.apply(RequestOptions().signature(ObjectKey(System.currentTimeMillis())))
.into(imageView)
- 또는 캐싱 전략을 사용할 수도 있다.
Glide.with(context)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.ALL) // 모든 버전 캐싱
.into(imageView)
- 마지막으로 아예 캐싱 기능 자체 사용 안함 설정이다
Glide.with(context)
.load(imageUrl)
.skipMemoryCache(true) // 메모리 캐시 사용 안 함
.into(imageView
위와 같이 캐싱 정책을 구성하는 여러가지 방법이 있다.
캐싱을 아예 사용 안하는 것은 역시 효율은 떨어질 수 있다.
하지만 시스템 스타일에 따라서 선택적일 듯하다.