Improve the performance of RecyclerView

Tram Ho

In my previous project, I was working on an app with a vertical list where every item in that list had a horizontal image list, like Instagram. And I have encountered some issues with that RecyclerView. If you search on google, you can find some useful solutions to improve performance, but in my case (maybe yours too) it doesn’t help! So, I decided to share my problem and my solution.

What is my problem?

  • RecyclerView when scrolling is not smooth.
  • The first few items scroll slowly
  • Horizontal photo sliders (like Instagram) do not work well

The first problem

As I said my first problem was about the smooth scroll of RecyclerView. I have a Vertical RecyclerView and each of its items has a photo slider, some text, review bars, favorite image buttons and buttons … as shown below.

As you can see, it’s not a complicated view, except for the photo slider, on the other hand we can see this photo slider in applications like Instagram and Airbnb and it works perfectly without latency.

The first thing I thought of was removing the photo slider, I just commented it to initialize from my adapter, but RecyclerView didn’t scroll smoothly.

So let’s solve this problem together

1. The first thing is to initialize RecyclerView

If it is possible to set the width and height of items in the XML file and they don’t change based on the content of the Adapter, add this line to your RecycleView Initialization method:


With this method, you told RecycleView not to calculate the size of the item each time they add and remove it from the RecycleView.

2. Another method is ItemViewCacheSize


Set the number of views offscreen to keep before adding them to the pool of views that can be recycled.

The off-screen view cache identifies changes in the attached adapter, allowing LayoutManager to reuse unmodified views without having to go back to the adapter to rebind them.

In other words, when you scroll RecyclerView so that there is a view almost completely off-screen, RecyclerView will keep it around so you can scroll it back into the view without having to execute the onBindViewHolder() method onBindViewHolder()

3. setHasStableIds method


and in your adapter this line of code

RecyclerView will try to summarize the visible structural change events for the adapters reporting that they have stable IDs when this method is used. This may help with the purpose of animation and object persistence, but item views will still need to be rebounded and relaid out.

These methods help you improve your RecyclerView performance and maybe they can solve all your problems, but in my case, my list is scrolling with bad lag especially on Samsung devices. so try to find other solutions besides these helpful methods.

After 2 days I found the problem, unfortunately, it’s about ConstraintLayout. I designed the layout of my items with ConstraintLayout and since many tags were bound it was very heavy, so I changed it to Linear and Relative layout and most of my problems were solved.

It’s great, ConstraintLayout is a great layout to design, it’s very easy to use and understand, but in this case, I think it’s really awful. It is very heavy for inflating and binding views.

Don’t use ConstraintLayout in RecyclerView

The second problem

The second problem is that some of the first items scroll slowly because onCreateViewHolder() has called the first 6 items. So, we have RecyclerView load all 6 items in the first initialization.

PreCachingLayoutManager is the solution

We can create a layout manager to load some offscreen (out of screen) items the first time.

This is the PreCachingLayoutManager extended from LinearLayoutManager. As you can see there is a method named setExtraLayoutSpace with a parameter. This method returns the amount of additional space needed to be arranged by LayoutManager, and the parameter has a unit of pixels, which means that if you want to preload items, you can set it to [DeviceHeight2] as the open layout space. wide.

But be careful, extra layout space is especially expensive. So after yours, some of the first loaded items set it to the default value.

The last problem

Here we have a vertical RecyclerView with some horizontal lists in each item. These horizontal lists are PhotoSlider and if you are looking for ways to implement PhotoSlider you will find lots of implement libraries using ViewPager.

But in this case, we have a lot of items, and of course there are a lot of ViewPagers for each item, so we have to face a bunch of Fragments just to show some pictures.

So I recommend using RecyclerView horizontally with linearSnapHelper() to act as ViewPager instead of ViewPager for PhotoSlider.

We have some optimizations here

When the user swipes to the side, RecyclerView will recyclers the views and lets the user scroll more smoothly. But this is not the case when users scroll vertically. Each view in RecyclerView is inflated. This is because each nested RecyclerView has its own view pool.

We can fix this by setting a single view pool for all RecyclerViews inside.

Lets you set custom view pools for your recyclerView, like the code below

Hope this article will be of much help to you.

Reference source:

Share the news now

Source : Viblo