이미지_로딩_기술_선정 - boostcampwm-2024/and04-Nature-Album GitHub Wiki

💡 이미지 로딩 기술 선정 개요

  • 우리 앱의 기능에서 이미지 로딩은 필수적인 작업이다. 이를 구현하는 방법은 여러가지가 있는데 크게 라이브러리 유무로 나눌 수 있다. 또한, 라이브러리를 사용하는 경우에는 Coil과 Glide를 비교하여 선정해야 할 것이다. 이에 대해서 라이브러리가 필요한지, 필요하다면 어떤 기술을 선택해야 하는 지에 대해 살펴보고자 한다.

💡 라이브러리 없이 이미지 로딩하기

로컬 이미지 로딩

  • 리소스 폴더의 이미지

    • ImageViewsetImageResource() 메서드를 사용하여 drawable 폴더에 있는 이미지를 로드할 수 있다.

      imageView.setImageResource(R.drawable.image_name)
      
    • painterResource를 사용하여 drawable 폴더에 있는 이미지를 로드할 수 있다.

      Image(
          painter = painterResource(id = R.drawable.image_name),
          contentDescription = "이미지 설명"
      )
      
  • 파일 시스템의 이미지

원격 이미지 로딩

  • 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 버전

  • 릴리즈 상태

    • 최신 버전은 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 환경에서 이미지를 쉽게 로드 가능
  • 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 컴포저블을 제공함
  • 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


💡 기술 선택 결론

1️⃣ 이미지 로딩 라이브러리를 사용할 것인가? ⇒ YES

현재 프로젝트 상황

현재 프로젝트는 로컬 저장소에 URI 기반으로 이미지를 저장할 에정이며, 추후 서버 연결 시 URI를 통해 서버에서 이미지를 불러오는 방식으로 확장될 예정이다.

이미지 로딩 라이브러리 사용의 적합성

위와 같은 상황에서 이미지 로딩을 라이브러리 없이 구현할 경우, 직접 캐싱, 비동기 처리, 메모리 관리 등을 처리해야 하므로 유지보수와 코드 복잡도가 증가할 위험이 있다.

따라서 이미지 로딩 라이브러리를 사용하는 것이 적합하며, 라이브러리를 사용한다면 현재 안드로이드 환경과 프로젝트 구성에 맞는 CoilGlide 중에서 선택해야 한다.

2️⃣ Coil과 Glide 중 어떤 것을 사용할 것인가? ⇒ Coil

Coil과 Glide의 적합성에 관하여

프로젝트는 Kotlin과 Jetpack Compose를 주로 사용하고 있으며, 이미지가 사용되는 대부분의 화면이 Compose로 구성되어 있다. Glide 또한 Compose 통합을 지원하지만, 주로 Java와 XML 기반의 뷰 시스템에 최적화되어 있고, Compose 통합이 최근 추가되어 아직 베타 단계이다. 반면, Coil은 Kotlin으로 작성되었으며 Compose에 대한 공식적인 지원을 지속해서 업데이트하고 있다. 최신 릴리즈까지 빠르게 제공되고 있고, OkHttp와 Coroutines를 사용하여 현대적인 비동기 처리 및 최적화된 메모리 관리가 가능하다.

이와 같은 이유로 Coil을 사용하여 프로젝트의 이미지 로딩을 관리하는 것이 가장 적합하다. Coil은 현재 프로젝트의 기술 스택 및 요구 사항에 부합하며, 코드의 간결성과 유지보수성을 높이는 데 유리하다.