Coil – lính mới xịn xò

Hẳn các bạn cũng đã quen dùng các thư viện Glide, Picasso, Fresco, Universal Image Loader, … để load ảnh. Đây đều là các thư viện đã xuất hiện từ lâu, có nhiều người sử dụng.

Bên cạnh đó, Kotlin ra đời, mang lại nhiều cái mới như chúng ta đã nói ở Series Kotlin vi diệu. Nhiều tính năng hay, sự tiện lợi, ngắn gọn là cái chúng ta đều biết.

Và không nằm ngoài cuộc chơi, Kotlin cũng có thư viện load ảnh của riêng mình, tên là Coil.

Bài viết sẽ giới thiệu về Coil, mục đích của nó khi được tạo ra, tính năng và so sánh với Glide, Picasso. Ok, giờ bắt đầu thôi !!!

Cảm ơn bạn đã đọc các bài viết của Code cùng Trung. Bạn hãy ủng hộ blog bằng cách:

  • Comment bên dưới mỗi bài nếu có thắc mắc
  • Để lại địa chỉ email của bạn để nhận được thông báo sớm nhất khi có bài viết mới
  • Chia sẻ các bài viết của Code cùng Trung đến nhiều người khác

I. Giới thiệu

1. Khái niệm

Coil là một thư viện load ảnh mã nguồn mở, được viết bằng Kotlin cho Android – viết bằng Kotlin nên sẽ cung cấp cho dev nhiều cái hay ho : ))

Coil được release lần đầu vào 12/08/2019.

Coil nhanh, nhẹ, dễ sử dụng, hiện đại và sử dụng Coroutines, OkHttp, Okio và AndroidX Lifecycles. Coil là viết tắt của “Coroutine Image Loader”

Coroutine Image Loader

2. Mục đích

  • Tận dụng tính năng có sẵn của Kotlin

Sử dụng … extension functions, inline, lambdasealed class để tạo ra những API đơn giản, dễ sử dụng

Extension functions và inline

Load ảnh bằng Coil như sau

imageView.load("https://www.example.com/image.jpg")

Để code được như trên, coil đã sử dụng extension function. Chi tiết bạn có thể xem tại github của coil. Dưới đây là một ví dụ

imageView.load()

Extension function phải không nào. Nếu chưa biết các bạn có thể xem tại bài viết này của mình.

Code trên cũng sử dụng higher-order function nên sẽ làm tăng bộ nhớ lên kha khá. Inline đơn giản sẽ làm giảm việc này.

Lambda function: Các bạn có thể tìm thấy nó được sử dụng ở rất nhiều chỗ trong code.

Seal classed: phiên bản mở rộng của Enum, giúp các bạn có thể làm được nhiều việc hơn. Các bạn có thể tìm hiểu thêm tại bài viết Kotlin và những cái mới mẻ – Phần 2

Ví dụ dùng sealed class trong Kotlin

Muốn xem nhiều chỗ dùng hơn các bạn có thể xem tại đây.

  • Tận dụng Kotlin Couroutines: cái tên của nó đã nói lên điều này rồi :)). Sử dụng Couroutine, sẽ hỗ trợ cho tính toán bất đồng bộ, tối ưu luồng và những tính năng hay khác mà couroutines mang lại
  • Những dependency hiện đại: coil sử dụng Square OkHttp và Okio, những thư viện hiện đại và rất hay được sử dụng. Chúng giúp coil tránh phải implement lại việc cache và bộ nhớ đệm. Đồng thời AndroidX Lifecycles giờ được yêu cầu để theo dõi vòng đời.

OkHttp Okio, những cái tên đã quá quen thuộc phải không nào:

  • OkHttp giúp việc xử lý load ảnh từ mạng trở nên an toàn, tiện lợi, nhanh chóng hơn, kèm khả năng cache rất tốt của nó.
  • Okio giúp việc truy cập, lưu trữ, xử lý dữ liệu, tạo bộ nhớ đệm tốt hơn nhiều.

Bạn có thể xem những chỗ dùng Okio trong Coil tại: https://github.com/coil-kt/coil/search?p=2&q=okio&unscoped_q=okio

AndroidX Lifecycles: một ví dụ như request load ảnh trong Coil sẽ được cancel khi View gắn với nó được detach, vòng đời gắn với nó (activity, fragment, service, …) bị destroy. Việc này sẽ tránh gây crash app.

Dependency xịn xò phết !!!
  • Nhẹ: coil có số dòng code ít hơn gần 8 lần so với Glide và ít hơn một chút so với Picasso.

So sánh chi tiết hơn mình sẽ để dành nói ở dưới nhá 😀

  • Tránh annotation processing: làm tăng tốc độ build. Thay vào đó Kotlin dựa vào extension functions.

3. Tính năng

  • Load ảnh từ URL, file, resource, …
  • Load ảnh png, gif, SVGs, video frames,
  • Preload: load trước ảnh vào bộ nhớ
  • Cancelling request: giúp hủy request load ảnh (từ link nào đó chẳng hạn). Ngoài ra còn có thể check đang trong quá trình load ảnh hay không, load ảnh phụ thuộc vào vòng đời, trạng thái.
  • Image sampling
  • Hỗ trợ Bitmap Pooling: tương tự như Glide và Fresco. Là một kỹ thuật để sử dụng lại các đối tượng Bitmap khi chúng không còn được sử dụng (tức là khi View được detached , view của Fragment bị hủy, v.v.). Điều này có thể cải thiện đáng kể hiệu năng bộ nhớ (đặc biệt là trên các thiết bị tiền Oreo)
  • Thêm hiệu ứng cho ảnh:  blurcircle crop, and grayscale, and rounded corners.
  • Load ảnh dùng Place holder – ảnh dùng khi chưa load xong và error image – ảnh dùng khi load ảnh bị lỗi
  • Callback khi ảnh được load xong

So sánh với Glide, Picasso thì cũng ổn phết !!!

Khá nhiều tính năng đó :))

Còn tính năng gì hay ho nữa các bạn share lại nhé 😀

II. So sánh với Glide, Picasso

Mình sẽ đi so sánh qua 4 tiêu chí:

  • Số lượng method của thư viện
  • Kích thước
  • Hỗ trợ ảnh GIF
  • Hiệu suất load ảnh

Những số liệu dưới đây là mình tổng hợp lại từ 2 nguồn, link chi tiết mình sẽ để ở phần tham khảo nhé

1.Số lượng method

Khi bật proguard, số phương thức mỗi lib thêm vào project của bạn là:

  1. Picasso: 235
  2. Glide: 1646
  3. Coil: 456 (483 khi hỗ trợ GIF)

Nhưng khi thêm số phương thức từ những dependency của nó

  1. Picasso: 1795 (okHttp, okio)
  2. Glide: 1974
  3. Coil: 3159 (okHttp, okio, coroutines) – 3236 (khi hỗ trợ GIF)

Ta thấy Coil có số lượng method ít nhất khi không tính các dependency của nó. Nhưng khi tính vào thì số lượng tăng lên đáng kể.

2. Kích thước thư viện (KB)

  1. Glide: 112
  2. Picasso: 162
  3. Coil: 250 (253 khi hỗ trợ GIF)

Coil là lớn nhất, sau đó đến Picasso rồi Glide. Có thể do Coil dùng nhiều dependency và code bằng Kotlin chăng ??

3. Hỗ trợ ảnh GIF

  • Glide: có
  • Coil: có
  • Picasso: không

Vậy là khi muốn load ảnh GIF bạn nên dùng Glide hoặc Coil nhé !!!

4. Hiệu suất load ảnh

Sẽ đo dựa trên việc load ảnh như sau

  • Thời gian load từng bức ảnh một với mỗi thư viện. Mỗi bức sẽ được load 10 lần, sau đó số liệu sẽ được lấy trung bình. Cụ thể hơn là thời gian tính từ lúc bắt đầu gọi load ở mỗi thư viện đến khi load xong và set vào imageview.
  • Thời gian load toàn bộ bức ảnh mỗi lần. Cũng sẽ test 10 lần. Chính là thời gian để toàn bộ các bức ảnh load rồi hiển thị hoàn toàn tới người dùng.

Chi tiết cách đo các bạn xem ở phần Tham khảo nhé. Kết quả thu được như sau:

Khi load từng bức ảnh

  • Glide là nhanh nhất, Picasso và Coil tương tự nhau
  • Từ Cache thì Glide ít hơn rõ rệt so vs Picasso, một chút so với Coil

Thời gian load toàn bộ các bức ảnh

  • Glide nhanh nhất, sau đó đến Picasso và cuối cùng là Coil.
  • Từ Cache thì Glide và Coil nhanh, chậm nhất là Picasso.

Chung quy lại Glide là ổn nhất nếu nói về tốc độ load ảnh. Coil thì tùy trường hợp, tuy nhiên bản thân mình thấy vẫn chưa nhanh lắm, cần cải thiện nhiều thêm.

Tóm lại

Coil là một thư viện còn non trẻ, được viết bằng Kotlin với sự hiện đại, đơn giản và dễ sử dụng.

Coil sử dụng nhiều tính năng của Kotlin, những dependency hiện đại, … để mang lại những trải nghiệm tốt nhất. Coil cũng có nhiều tính năng mà các thư viện load ảnh nổi tiếng khác cũng có.

Về mặt hiệu năng – có lẽ đây là điều mà nhiều người quan tâm đến đầu tiên thì thực sự mong nó sẽ được cải thiện trong thời gian tới.

Nên dùng hay không ư ? Mình nghĩ các bạn cũng nên thử trải nghiệm xem.

Cuối cùng, mình xin để nguyên văn lời tác giả của Coil comment ở bài viết so sánh giữa các lib. Mong tương lai mọi thứ sẽ tốt hơn vs Coil 😀

Bạn nào có nhu cầu học Kotlin có thể tham khảo khóa học sau của Duy Thanh – một cái tên rất nổi tiếng nhé, rất chi tiết và bổ ích đó !

Tham khảo

  1. Thông tin về Coil

https://coil-kt.github.io/coil/

https://medium.com/better-programming/how-to-use-coil-kotlins-native-image-loader-d6715dda7d26

https://tech.instacart.com/introducing-coil-kotlin-first-image-loading-on-android-f0fdc7a2a99e

  • 2. So sánh giữa các thư viện

https://alexandroid.net/picasso-vs-glide-vs-coil/

https://proandroiddev.com/coil-vs-picasso-vs-glide-get-ready-go-774add8cfd40

Leave a Reply