
Glide 사용하고 계신가요?
안드로이드 개발자들이 가장 사랑하는 이미지 처리 라이브러리입니다. 저 또한 애용 중이며, 많은 분들께서 사용 중이시리라 생각합니다. 수많은 메서드를 통해 이미지 수정 및 처리가 가능하고 Third-Party-Library도 많은 데다가 gif까지 훌륭히 지원하니, 놀랍도록 우수한 라이브러리가 등장하지 않는 이상은 Glide가 다른 라이브러리에게 자리를 내어줄 일은 없어 보입니다.
Glide는 기본적인 캐시(Cache)를 지원하고 있습니다. 그럴 수 밖에 없는 것이, 앱 내 리소스에 이미지를 포함시키기에는 너무나 방대한 양의 이미지 파일을 저장해야 하는 경우가 많을 것이기 때문입니다.
아래는 제가 직접 제작한 1인 개발 앱 <에이펙싱>입니다. 저는 Glide에 기본 캐시가 있다는 것을 앱 사용 중 알게 되었습니다.
기본적으로, Glide는 새로운 이미지 요청에 대한 작업을 수행하기 전 캐시들의 여러 계층을 살펴봅니다.
1. Active Resources - 해당 이미지가 현재 다른 View에 표시되고 있는가?
2. Memory Cache - 해당 이미지가 최근에 불러와졌고, 여전히 메모리에 있는가?
3. Resource - 해당 이미지가 디코딩되고, 안드로이드에 맞게 변경되었으며, 디스크 캐시에 쓰인 적 있는가?
4. Data - 해당 이미지가 앱 내 Resources로부터 불러와졌는가?
1번 또는 2번에 해당하는 경우 Glide는 즉각적으로 해당 이미지를 불러옵니다.
현재 메인 메모리에 적재되어 있기 때문에 바로 참조해서 가져오면 됩니다.
3번 또는 4번에 해당하는 경우 Glide는 1, 2번의 경우보단 느리지만 그래도 빠르게 불러옵니다. 단, 비동기 작업을 수행합니다. 3번의 경우 디스크 캐시에서 가져올 것이며, 4번의 경우 앱 내에서 가져옵니다.
모든 단계에 전혀 해당하지 않을 경우, Glide는 다시 원본 소스에서 데이터를 받아옵니다.
(ex. Uri, Url, resources 내의 이미지 파일)
캐시 전략
디스크 캐시 전략 (DiskCacheStrategy)
DiskCacheStrategy는 개별 작업에 대해 diskCacheStrategy()를 통해 적용할 수 있습니다.
원본 이미지 그대로를 캐시 할 수도 있고, 앱에 맞게 변형된 이미지를 캐시 할 수도 있습니다.
(두 개 모두 한 번에 할 수도 있습니다.) 파라미터로는 DiskCacheStrategy의 세부 전략이 들어갑니다.
세부 전략은 다음과 같습니다.
ALL - 네트워크를 통해 얻어 온 이미지는 데이터와 리소스, 로컬 이미지는 리소스만을 캐시 합니다.
(데이터는 원본을 의미하며, 리소스는 앱에 맞게 변형된 이미지를 의미합니다.)
DATA - 반환받은 데이터를 그 데이터가 디코딩되기 전에 디스크에 직접 씁니다.
RESOURCE - 앱에 맞게 디코딩된 이미지를 디스크에 씁니다.
AUTOMATIC - 데이터 소스의 유형을 스스로 분석해서 적합한 디코딩 및 인코딩 전략에 따라 캐시 합니다.
NONE - 캐시를 하지 않습니다.
이미지를 캐시에서만 불러올 수 있는 방법도 있습니다.
Glide.with(binding.root)
.load(url)
.onlyRetrieveFromCache(true)
.into(imageView)
해당 방식은 메모리 캐시나 디스크 캐시에 이미지가 존재하면 로드되고, 아니면 실패합니다.
캐시 건너뛰기
특정한 경우 (온보딩 화면에 사용되는 이미지, 스플래쉬 스크린 등) 디스크 캐시나 메모리 캐시에 쓰기 작업 자체를 진행하지 않도록 설정할 수도 있습니다. 이 역시 당연히 메모리 캐시, 디스크 캐시 모두 설정할 수 있습니다.
// 메모리 캐시만 수행하지 않도록
Glide.with(binding.root)
.load(url)
.skipMemoryCache(true)
.into(imageView)
// 디스크 캐시만 수행하지 않도록
Glide.with(binding.root)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageView)
// 메모리 캐시 및 디스크 캐시 모두 수행하지 않도록
Glide.with(binding.root)
.load(url)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageView)
물론 요즘에야 기기 성능도 충분히 좋고, 디바이스 스토리지도 과거에 비해 굉장히 커서 캐시를 하지 않는 선택지가 굳이 필요하지는 않겠습니다. 하지만 기술했듯 특정한 상황의 경우, 자원을 낭비하지 않기 위해 선택할 수 있는 좋은 선택지가 아닌가 싶습니다.
Glide의 디스크 캐시 및 메모리 캐시는 LRU(Least Recently Used) 알고리즘으로 작동합니다.
다만 추가적인 몇 가지 방법으로 직접 리소스를 관리할 수도 있습니다.
메모리 캐시의 크기를 확장할 수 있는데요. 당연히 메모리 캐시의 크기를 확장하면 더 많은 이미지를 캐싱할 수 있고, 그에 따라 더 많은 이미지에 빠르게 액세스 할 수 있겠습니다. 하지만 캐시 크기를 확장하면 앱 용량도 덩달아 커지기 때문에 성능과 앱 용량에 대한 상충 관계를 잘 따져보아야 합니다.
메모리 캐시의 사이즈는 앱 전체에 걸쳐 확장 또는 축소할 수 있고, 일시적으로도 가능합니다.
디스크 캐시의 사이즈는 빌드시 자동으로 생성되는 AppGlideModule에서 확장 또는 축소가 가능하고 이는 일시적으로 변환할 수 없습니다.
다만, 디스크 캐시를 의도적으로 비워줄 수는 있습니다. 물론 메모리 캐시도 비울 수 있습니다.
// 디스크 캐시를 비우고 싶을 때
Glide.get(context).clearDisckCache()
// 메모리 캐시를 비우고 싶을 때
Glide.get(context).clearMemory()
Glide를 꽤 오랜 시간 사용하면서 캐시가 되는 것은 알았지만, 이렇게 다양한 기능까지 지원하는 줄은 몰랐습니다.
캐시를 잘 사용하면 필요 없는 데이터를 줄여 유저로 하여금 더 많은 디바이스 잔여 저장 공간을 운용할 수 있도록 할 수 있겠습니다.
'Android > Tech' 카테고리의 다른 글
[Jetpack Compose] Clickable Ripple Effect 없애기 (0) | 2022.12.05 |
---|---|
[Jetpack Compose] 상태 호이스팅 (0) | 2022.11.24 |
[Dagger-Hilt] ActivityScope 와 ActivityRetainedScope 의 차이 (0) | 2022.10.21 |
Coroutine Dispatcher 란 무엇인가? (0) | 2022.10.19 |
Fragment Lifecycle 과 UX (feat.Navigation Component) (0) | 2022.06.03 |