이미지_로딩_기술_선정 - boostcampwm-2024/and04-Nature-Album GitHub Wiki
💡 이미지 로딩 기술 선정 개요
- 우리 앱의 기능에서 이미지 로딩은 필수적인 작업이다. 이를 구현하는 방법은 여러가지가 있는데 크게 라이브러리 유무로 나눌 수 있다. 또한, 라이브러리를 사용하는 경우에는 Coil과 Glide를 비교하여 선정해야 할 것이다. 이에 대해서 라이브러리가 필요한지, 필요하다면 어떤 기술을 선택해야 하는 지에 대해 살펴보고자 한다.
💡 라이브러리 없이 이미지 로딩하기
로컬 이미지 로딩
-
리소스 폴더의 이미지
-
ImageView
의setImageResource()
메서드를 사용하여drawable
폴더에 있는 이미지를 로드할 수 있다.imageView.setImageResource(R.drawable.image_name)
-
painterResource
를 사용하여drawable
폴더에 있는 이미지를 로드할 수 있다.Image( painter = painterResource(id = R.drawable.image_name), contentDescription = "이미지 설명" )
-
-
파일 시스템의 이미지
-
BitmapFactory
를 사용하여 기기 내 파일 시스템에 저장된 이미지를 로드할 수 있다.val bitmap = BitmapFactory.decodeFile(filePath) imageView.setImageBitmap(bitmap)
-
https://developer.android.com/topic/performance/graphics/load-bitmap?hl=ko
-
원격 이미지 로딩
- HTTP 요청
-
HttpURLConnection
을 사용하여 네트워크를 통해 이미지를 다운로드한 후,BitmapFactory
로 디코딩하여ImageBitmap
으로 변환한 뒤 표시val url = URL(imageUrl) val connection = url.openConnection() as HttpURLConnection connection.doInput = true connection.connect() val input = connection.inputStream val bitmap = BitmapFactory.decodeStream(input) val imageBitmap = bitmap.asImageBitmap() Image( bitmap = imageBitmap, contentDescription = "이미지 설명" )
-
라이브러리를 사용하지 않는 경우의 주의사항
- 라이브러리를 사용하지 않을 경우 메모리 관리, 캐싱, 스레드 처리 등 복잡한 작업을 직접 구현해야 한다. 제대로 구현하지 못하거나 실수할 경우 메모리 누수나 성능 저하의 원인이 될 수 있다.
💡 라이브러리를 사용하는 경우
- 위에서 언급한 복잡한 작업(캐싱, 스레드 처리 등)을 간소화 할 수 있어 편리하다.
- 이미지 로딩에서 언급되는 대표적인 라이브러리인 Coil과 Glide를 살펴보자.
Coil
https://github.com/coil-kt/coil
https://coil-kt.github.io/coil/getting_started/
-
최소 지원 API 버전
- The minimum supported API is now 21.
- https://coil-kt.github.io/coil/changelog/
-
릴리즈 상태
- 최신 버전은 3.0.0
implementation("io.coil-kt.coil3:coil-compose:3.0.0") implementation("io.coil-kt.coil3:coil-network-okhttp:3.0.0")
- Kotiln 2.0.10, Compose 1.6.8, SDK 35
-
Compose 지원 여부 → O
- Coil은 Jetpack Compose를 공식적으로 지원하며,
coil-compose
모듈을 통해 Compose 환경에서 이미지를 쉽게 로드 가능
- Coil은 Jetpack Compose를 공식적으로 지원하며,
-
Kotlin 기반 여부
- Coil은 Kotlin으로 작성된 라이브러리로, Kotlin의 언어 기능과 Coroutines를 활용하여 간결하고 효율적인 API를 제공
-
다른 라이브러리와의 통합
- Coil은 OkHttp, Okio 등과 같은 최신 라이브러리와 통합되어 있으며, Coroutines를 활용하여 비동기 이미지 로딩을 지원
-
구현 기반
- Coil은 Kotlin Coroutines를 기반으로 하며, OkHttp와 Okio를 사용하여 네트워크 요청과 파일 입출력을 처리
https://github.com/coil-kt/coil?tab=readme-ov-file
- Fast: Coil performs a number of optimizations including memory and disk caching, downsampling the image, automatically pausing/cancelling requests, and more.
- Lightweight: Coil only depends on Kotlin, Coroutines, and Okio and works seamlessly with Google's R8 code shrinker.
- Easy to use: Coil's API leverages Kotlin's language features for simplicity and minimal boilerplate.
- Modern: Coil is Kotlin-first and interoperates with modern libraries including Compose, Coroutines, Okio, OkHttp, and Ktor.
- Java 호환성
-
Coil은 Kotlin을 우선으로 설계된 API로, inlined 람다, receiver 매개변수, 기본 인수, 확장 함수와 같은 Kotlin 언어 기능을 활용 ⇒ 이러한 기능 Java에서 사용 불가 ⇒ 제약 있음
- 특히, suspend 함수는 Java에서 구현할 수 없기 때문에 사용자 정의 Transformations, Size Resolvers, Fetchers, Decoders는 Kotlin으로 구현해야 함
-
위의 제약이 있기는 하지만 Coil의 대부분의 API는 Java와 호환 가능
-
예를 들어 싱글톤 ImageLoader 가져오는 방법
ImageLoader imageLoader = SingletonImageLoader.get(context);
-
-
이외의 Java에서의 Coil 사용은 아래의 링크 참고
-
- XML 및 Compose 지원 여부 → O
- XML 기반의 뷰 시스템과 Jetpack Compose를 모두 지원
- XML에서는
ImageView
의 확장 함수의load()
사용하고, Compose에서는AsyncImage
컴포저블을 제공함- Getting Started의 Compose UI, Android Views 참고
- https://coil-kt.github.io/coil/getting_started/
- Lazy 관련 성능 이슈
- Lazy Grid/Row/Column등으로 여러 AsyncImage 컴포저블을 그릴때 캐시가 없을경우 렌더링이 매우 느려짐
- 🤔 부모 컴포저블을 고정 높이로 지정할 경우 문제가 해결된다는 말이 있는데 확인 필요 ← 그래도 문제가 발생한다는 사용자가 있음,
LazyVerticalStaggeredGrid
에서 고정 높이가 가능할까??- 2024.11.05 Coil이 3.0.0으로 릴리즈 되어 이 부분이 해결 된 상태로 릴리즈 됐는지 확인 필요
- https://github.com/coil-kt/coil/issues/1866
- https://github.com/coil-kt/coil/issues/2584
Glide
https://github.com/bumptech/glide
-
최소 지원 API 버전
Android SDK Requirements Minimum SDK Version - Glide requires a minimum SDK version of 14 (Ice Cream Sandwich) or higher. Compile SDK Version - Glide must be compiled against SDK version 27 (Oreo MR1) or higher.
-
릴리즈 상태
- 현재 Glide는 5.0.0-rc01(Release Candidate) 버전을 제공
https://github.com/bumptech/glide/releases/tag/v5.0.0-rc01
https://github.com/bumptech/glide/releases
- 5.0.0 베타 버전
- 4.16.0
- Compose 지원은 2022년 9월 29일에 출시된 버전 4.14.0에서 처음 도입
- 2023년 8월 21일에 출시된 버전 4.16.0에서 Compse 관련 기능 향상
- Compose 전용 전환 효과(예: 크로스 페이드)와 GlideSubcomposition을 통한 요청 상태 기반의 재구성이 추가 등
- Glide는 2023년 9월 27일 5.0.0-rc01(Release Candidate) 버전을 통해 Compose 지원을 더욱 강화 중
- Kotiln 1.9, Compose 1.0.0 Beta
-
Compose 지원 여부
- 베타버전 & 릴리즈 1년 전이 마지막
-
Kotlin 기반 여부
- Glide는 Java로 작성된 라이브러리이지만 호환 가능
-
다른 라이브러리와의 통합
-
OkHttp, Volley 등 다양한 네트워크 스택과의 통합을 지원하여 유연한 네트워크 요청 처리가 가능
https://github.com/bumptech/glide/wiki/Integration-Libraries Currently Glide includes integration libraries for performing all http/https operations with [Volley](http://developer.android.com/training/volley/index.html) and [[OkHttp](http://square.github.io/okhttp/)](http://square.github.io/okhttp/).
-
-
구현 기반
- Java로 구현되었으며, 이미지 디코딩, 메모리 및 디스크 캐싱, 리소스 풀링 등을 통해 효율적인 이미지 로딩을 제공
-
Java 호환성
- Java로 작성되었으므로, Java 프로젝트에서 직접 사용하기에 적합
- Kotlin 호환 O
-
XML 및 Compose 지원 여부
- XML 기반의 뷰 시스템을 공식적으로 지원
💡 기술 선택 결론
1️⃣ 이미지 로딩 라이브러리를 사용할 것인가? ⇒ YES
현재 프로젝트 상황
현재 프로젝트는 로컬 저장소에 URI 기반으로 이미지를 저장할 에정이며, 추후 서버 연결 시 URI를 통해 서버에서 이미지를 불러오는 방식으로 확장될 예정이다.
이미지 로딩 라이브러리 사용의 적합성
위와 같은 상황에서 이미지 로딩을 라이브러리 없이 구현할 경우, 직접 캐싱, 비동기 처리, 메모리 관리 등을 처리해야 하므로 유지보수와 코드 복잡도가 증가할 위험이 있다.
따라서 이미지 로딩 라이브러리를 사용하는 것이 적합하며, 라이브러리를 사용한다면 현재 안드로이드 환경과 프로젝트 구성에 맞는 Coil과 Glide 중에서 선택해야 한다.
2️⃣ Coil과 Glide 중 어떤 것을 사용할 것인가? ⇒ Coil
Coil과 Glide의 적합성에 관하여
프로젝트는 Kotlin과 Jetpack Compose를 주로 사용하고 있으며, 이미지가 사용되는 대부분의 화면이 Compose로 구성되어 있다. Glide 또한 Compose 통합을 지원하지만, 주로 Java와 XML 기반의 뷰 시스템에 최적화되어 있고, Compose 통합이 최근 추가되어 아직 베타 단계이다. 반면, Coil은 Kotlin으로 작성되었으며 Compose에 대한 공식적인 지원을 지속해서 업데이트하고 있다. 최신 릴리즈까지 빠르게 제공되고 있고, OkHttp와 Coroutines를 사용하여 현대적인 비동기 처리 및 최적화된 메모리 관리가 가능하다.
이와 같은 이유로 Coil을 사용하여 프로젝트의 이미지 로딩을 관리하는 것이 가장 적합하다. Coil은 현재 프로젝트의 기술 스택 및 요구 사항에 부합하며, 코드의 간결성과 유지보수성을 높이는 데 유리하다.