Recycler view + Glide (Load a lot of images really fast)

·

4 min read

What are some issues in normally loading URL

What a recycler view basically does is that it uses the view that you just scrolled up and updates its parameters and uses it to display your next item in the list.

Now, this is extremely efficient and really great for normal views, But if you have images that are not of the same size, this can cause a lot of issues in the form of hard resizing when scrolling back up.

So that is our issue 1. hard resizing of image when scrolled back.

Next, Image loading time and while the image is loading a loader icon

So the issue here is that glide is super efficient in loading images in smaller quantities but as it internally does not use Coroutines, it is not very efficient when it comes to more images.

Thats our next issue 2. longer loading times.

Next is actually how we pass or update our data for the recyclerView. The main issue here is if we only have one new addition, we still pass the entire dataset to the adapter.

That is our last issue 3. inefficient adapter communication.

Solutions and why they work:

Okay so lets deal with the situation issue wise

Issue 1

As the reason is that we have not set fixed size for our image view to accommodate multiple view sizes and thus what happens is, As mentioned earlier, recyclerview uses the same view that is not visible and updates it's values in onBindViewHolder and shows it to us. In this process as we might have kept height/ width as wrapcontent, glide tries to load the new image in the old formfactor with the old dimensions and this causes issues.

To avoid that

Solution:

Just before loading the url into image inside onBindViewHolder call this: holder.image.layout(0,0,0,0) This will resize the image to 0 and glide will only use the parameters and dimensions of the current image only.

Issue 2

Okay so this works in 2 ways one is delay in passing the data which will be addressed in issue3 but will effect performance and loading a lot.

So here, we will look how to make loading faster and add a loading image meanwhile.

Solution:

As the image loading deals with UI, All UI tasks must be performed on Main thread only so we will be using CoroutineScope(Dispatchers.Main) and inside its launch method, we will perform the holder.image.layout(0,0,0,0) and the actual loading inside of this coroutine. Dependency for coroutines:

//coroutines
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'

This does significantly improve loading times but we do need a image to appear until that happens.

For that do:

Glide.with(holder.image.context).placeholder(drawable).load(URL).into(holder.image)

here passing image's context also helps in performance.

Issue 3

Okay this one is simpler as it just deals with how we pass the data, adapter:

Solution:

so this is how I suggest you to implement that:

val mAdapter = RecyclerAdapter(imageList)
rv_recycler.adapter = mAdapter

// for updating the values
mAdapter.notifyItemInserted(item_position)
mAdapter.notifyItemRemoved(item_position)
mAdapter.notifyItemChanged(item_position)

As discussed earlier, they are efficient as they do not update all the items but only those are changed or added. Rest of the recycler view boilerplate code remains the same. Again this can be made more efficient by using coroutines.

Conclusion & Other tips.

This are few methods by which I was able to make my recyclerview load images with glide a lot better and in the process I also learned a lot about Glide and RecyclerView and some additional points that I have not implemented and would also not like to comment on but just putting it here if that helps someone:

  1. Try different caching strategy for glide.
  2. Try usign DiffUtil for recyclerview it is method by which the updates are more efficent.
  3. Additionally you can even add shimmer view as placeholder to make it animated.
  4. Coil uses threading internally that could give better results.
  5. ViewBinding and updating viewmodel via a livedata observer could also be a efficient way.

That's all for today guys! Thanks for sticking till the end, if you learned something new please leave a reaction. Have a lovely day! Thanks.