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

Mihir Shah
3 min readSep 4, 2021
Banner

Let us first understand what are some issues faced while normally loading image from URL

So, what a recycler view basically does is that it uses the view that you just scrolled up and updates its parameters and uses it or “recycles” it to display your next item in the list.

Let’s break them down into 3 issues:

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 and longer loading times 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.

That’s 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

The reason for the issue 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 dimensions and glide will only use the parameters and dimensions of the current image.

Issue 2

Okay, so this is caused due to 2 things, one is delay in passing the data which will be addressed in issue3 but it will effect performance and loading a lot.

So here, we will look how to make loading faster and add a loader 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:

COPY

//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 (placeholder).

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, these methods are efficient as they do not update all the items but only those which 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.

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

  1. Try different caching strategy for glide.
  2. Try using DiffUtil for recyclerview, it is method by which the updates are more efficient.
  3. Additionally you can even add shimmer view as placeholder to make it animated.
  4. Coil another library like Glide 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.

--

--

Mihir Shah

Android developer with love for open source softwares.