anvil icon indicating copy to clipboard operation
anvil copied to clipboard

Would be possible to run the diff tree algorithm in a non UI thread?

Open niltonvasques opened this issue 6 years ago • 3 comments

We are using Anvil in our project for 2 years now. And in some screens, with a high number of views, we are facing some performance issues. These delays and lags happens even when no changes are made to the views, but a render cycle is fired because a button was clicked for example.

Based on this, I would like to know if would be possible to perform the Anvil diff tree algorithm in a non UI thread, thus the screen will not be affected by these comparisons. The idea is only to use the UI thread once we detected that we need to update a View, add a view or remove a view.

niltonvasques avatar Oct 03 '19 11:10 niltonvasques

Are sure that those issues are related to diff process? As quick fix I can suggest to not use Anvils onClick(..) methods, but set onClick listeners manually in order not to fire render() on every user input.

sgrekov avatar Oct 04 '19 09:10 sgrekov

Hello @sgrekov,

In our project we don't use anymore the native Anvil listeners, however we do call render method in other situations which leads to the same issue. My example with the onClick was just to be more easy and simple to illustrate the problem.

I just created a toy layout to show this issue in action:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(object : FrameLayoutComponent(this) {
            override fun view() {
                render()
            }

            private fun render() {
                val size = 500
                linearLayout {
                    width(MATCH)
                    height(MATCH)
                    weightSum(10f)
                    orientation(VERTICAL)

                    scrollView {
                        width(MATCH)
                        height(0)
                        BaseDSL.weight(9f)

                        linearLayout {
                            backgroundColor(Color.DKGRAY)
                            orientation(VERTICAL)

                            for (i in 0..size) {
                                row(i)
                            }
                        }
                    }

                    button {
                        text("render")
                        onClick {
                            Toast.makeText(this@MainActivity, "render firing!!", Toast.LENGTH_LONG).show()
                        }
                    }
                }
            }

            private fun row(i: Int) {
                linearLayout {
                    textView {
                        text("$i setText")
                        textColor(Color.WHITE)
                        BaseDSL.margin(dip(10))
                    }
                    textView {
                        text("$i setText")
                        textColor(Color.RED)
                        BaseDSL.margin(dip(10))
                    }
                    textView {
                        text("$i setText")
                        textColor(Color.BLUE)
                        BaseDSL.margin(dip(10))
                    }
                    textView {
                        text("$i setText")
                        textColor(Color.YELLOW)
                        BaseDSL.margin(dip(10))
                    }
                    textView {
                        text("$i setText")
                        textColor(Color.MAGENTA)
                        BaseDSL.margin(dip(10))
                    }
                }
            }
        })
    }

Here I attached a video showing these blocking issues on the UI thread just because the diff algorithm from layout above. Since this is a fully static layout, in my opinion this issue should not happens because there are no view changes after the first render cycle. But anvil uses the main thread to perform also the diff.

render_blocking_ui_thread.zip

niltonvasques avatar Oct 04 '19 11:10 niltonvasques

Thanks for sample! Will take a look.

sgrekov avatar Oct 04 '19 12:10 sgrekov