Dimezis/BlurView

Performance issue while using BlurView in RecyclerView items

yusufonderd opened this issue · 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 ?

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.

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

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

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

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.

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

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

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 🙏🏼

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.