Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
niltonvasques opened this issue Oct 3, 2019 · 3 comments

Comments

@niltonvasques
Copy link

niltonvasques commented Oct 3, 2019

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.

@sgrekov
Copy link
Collaborator

sgrekov commented Oct 4, 2019

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.

@niltonvasques
Copy link
Author

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

@sgrekov
Copy link
Collaborator

sgrekov commented Oct 4, 2019

Thanks for sample! Will take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants