BlurView icon indicating copy to clipboard operation
BlurView copied to clipboard

Performance issue while using BlurView in RecyclerView items

Open yusufonderd opened this issue 3 years ago • 9 comments

Please include:

  1. 1.6.6
  2. Pixel 2 API 30
  3. Lagging occurs when using blurview in recyclerview. Every recyclerview item has a blurview. I setup blurview in onBindViewHolder method.
  4. Xml and blurview setup
// CustomRecyclerViewAdapter.kt

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
blurView.setupWith(rootBlurView)
          .setBlurAlgorithm(renderScriptBlur)
          .setBlurRadius(4f)
          .setHasFixedTransformationMatrix(false)
}

// item_recyclerview.xml

<FrameLayout
            android:id="@+id/rootBlurView"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginHorizontal="16dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent">

            <eightbitlab.com.blurview.BlurView
              android:id="@+id/blurView"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              app:blurOverlayColor="#78ffffff"/>

          </FrameLayout>
  1. Stacktrace in case of a crash There isn't any crash only occurs lagging and slow performance while scrolling recyclerview. What is the correct way setup BlurView ? Where can i setup BlurView ?

yusufonderd avatar Mar 23 '21 04:03 yusufonderd

It lags because you set it up in onBindViewHolder, which causes plenty of allocation on scroll.

What you need to do is to set it up in ViewHolder constructor once.

And please check old issues before posting a new one.

Dimezis avatar Mar 23 '21 08:03 Dimezis

Thanks for your response. What do you mean viewHolder constructor ? Which part of Recyclerviewadapter ?

yusufonderd avatar Mar 23 '21 08:03 yusufonderd

You don't need to set up BlurView each time onBindViewHolder is called. Do it once in onCreateViewHolder or in ViewHolder constructor.

Dimezis avatar Mar 23 '21 09:03 Dimezis

Thanks a lot. I set in onCreateViewHolder but it doesn't affect. Lagging still occurs :/ Maybe I will create pull request about recyclerview page sample in this repo. If you want too

yusufonderd avatar Mar 23 '21 10:03 yusufonderd

You can just create a sample repo and I will take a look at your code. Because I have a feeling that you're still doing something wrong, or have a misconfigured RecyclerView (lacking a sufficient number of ViewHolders in the recycler pool or something like that) or maybe inefficient View hierarchy.

On the side note, having a BlurView in each list item is a really bad idea in any case, it will have a big impact on the performance no matter what, especially on weak devices.

Dimezis avatar Mar 23 '21 10:03 Dimezis

Hi, Here is the sample project: https://github.com/yusufonderd/BlurViewExample You can show lagging when fast scroll especially when scrolling is over.

yusufonderd avatar Mar 26 '21 11:03 yusufonderd

I can suggest you to make list item much simpler, right now it has plenty of redundant Views that serve no purpose. Something like that, just add elevation and rounded corners drawable to the ConstraintLayout.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/blurViewRoot"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp"
    app:elevation="@dimen/item_photo_card_view_elevation">

    <ImageView
        android:id="@+id/ivBackground"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="H,10:5"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/img_item_background" />

    <eightbitlab.com.blurview.BlurView
        android:id="@+id/blurView"
        android:layout_width="0dp"
        android:layout_height="@dimen/item_photo_blur_view_height"
        android:layout_gravity="bottom"
        android:layout_marginHorizontal="@dimen/item_photo_blur_view_margin_horizontal"
        android:layout_marginBottom="@dimen/item_photo_blur_view_margin_bottom"
        android:background="@drawable/bg_blur_item_photo"
        app:blurOverlayColor="@color/blur_overlay"
        app:layout_constraintBottom_toBottomOf="@id/ivBackground"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:textAppearance="@style/TextAppearance.AppCompat.Headline"
            android:textColor="@color/white"
            tools:text="Title" />

    </eightbitlab.com.blurview.BlurView>

</androidx.constraintlayout.widget.ConstraintLayout>

Items will inflate faster and also BlurView will have much less work to do. Generally, try to keep your View hierarchy simple and set the root of the BlurView as close as possible.

This will not completely fix your problem, because as I said, having multiple BlurViews like this is a performance hit no matter what.

You can also try to create a custom LinearLayoutManager and override calculateExtraLayoutSpace to sort of preload off-screen Views of the list because during fast scrolling RecyclerView can create additional ViewHolders, which is a heavy operation with a BlurView. This trick, in theory, can pre-create enough ViewHolders on start when scrolling is not yet started.

But your best bet would be not to use it in the list

Dimezis avatar Mar 26 '21 19:03 Dimezis

As you say, I changed view hieararch then scroll performance increased enough in this sample. But it will not easy in my real project to fix as much. But i will try. Thank you very much for your attention 🙏🏼

yusufonderd avatar Mar 26 '21 19:03 yusufonderd

Unfortunately, when i'm trying to real project, it is not working as expected. Because i have to use Coordinator layout and cardview in my view holder. I can't fix the problem yet but i will write below this issue if there is an improvent.

yusufonderd avatar Mar 30 '21 18:03 yusufonderd