How’s compose perf for frequently updating UI? I h...
# compose
j
How’s compose perf for frequently updating UI? I have a screen which displays a feed of data updating every 100ms. In React I would normally separate something which frequently updates into its own small component, do these sorts of optimisations also hold true in compose?
t
If you do it right Compose will only update the component where changed data is used.
j
Do you mean it will only update the section of the tree where the data is used? So its fine to observe frequently updating data at the top of a large component because compose will only recompose the section of the tree where it’s consumed?
Or will the whole composable re-run each time the frequently updating data changes
t
Yes i think so. But they are still working on optimizations. In my experience it works fine. But it is not so easy to get every thing right. So you should use a special class which hold the changing data:
Copy code
class DataClass(val data: Float) {
        var data by mutableStateOf(data)
    }
You create on instance of this class and change it when you get new data. Compose will detect this changes.
You could also use LiveData or create you own observer using
Copy code
DisposableEffect
So it depends what fits best four you problem.
r
When a state variable changes, recomposition only occurs in places where that variable is directly used. That is why it is advisable to have very few stateful composables.
j
@Jason Ankers Same design principles apply. Compose does a slightly better job of optimizing than React in many use cases, but the same optimization knowledge you have from React will largely carry over.
That said, always remember to measure first, and let your measurements guide your optimizing.
👍 1
💯 1
j
Ok cool thats good to hear. So just to be clear from what the other said above: Say I have a large composable where I observe a frequently updating livedata source. If I’m consuming that data with just a bunch of Text(..) composables lower down, will just those Text(..) composables recompose when the data changes? If so, then thats a huge improvement over React
s
As far as I can remember , I believe only composable which consume certain state gets recomposed ,in your case that would be Text() composables. So large Composable wont recompose unless large Composable consume the same state itself.
j
It depends on a number of factors (for instance, if the Compose Compiler is able to prove certain properties about the data being passed from parent to child), so I can't easily give a general answer that will be 100% accurate.  Compose does a better job than React in most of the situations you mentioned, but it is not perfect, and performing the reads/observations within your children will better guarantee that updates happen in the manner you expect/desire. Keep in mind that a "children lambda" is a composable widget in Compose (unlike React), so that helps a lot, it makes it easy/natural for you to accidentally fall into the pit of success where your reads are happening in the children.
d
Compose does a better job than React in most of the situations you mentioned
How do you compare them? Do you have any benchmarks?
j
@Denis I was previously one of about 5 engineers on the React.js core engineering team, so I'm quite familiar with the classes of optimizations that are and are not possible in React. When I first started designing Compose, I made sure that the design decisions were compatible with the additional classes of optimizations that I wanted to see in Compose, many of which we've implemented. So I'm speaking in broad strokes about the types of situations that occur, and how the systems handle them. Having said that, keep in mind that React is significantly older than Compose and has thus had more time to polish their performance profiles, so there are still places where Compose needs to catch up, but I'm confident in our architecture and we've already seen great benefits from our approach. This is one of the reasons we have a custom Compose Compiler instead of being predominantly a runtime library.
👍 4
d
I was previously one of about 5 engineers on the React.js core engineering team
Oh! Thanks for the answer, Jim.
additional classes of optimizations
That's very interesting topic. Is there a public list of them somewhere we can read?
s
@jim sounds like compose is gonna do gr8 once released , as it already is doing wonders and all the effort you guys put is something!, I have one question , somewhat offtopic, As G is now putting whole lot efforts in Compose , Android etc , there was some news about fuchsio os and its future , so if you have any idea , plz enlight us too,again sorry about being off-topic.
j
@Denis We've talked a bit about some of them in the slack channel, maybe I'll write a blog post or something on the topic at some point. But the differences basically boil down to (1) avoid allocations, this is one of the key reasons we use a function-call syntax instead of returning elements like React/Flutter (2) Compiler analysis to determine when/where things are used and when/where things have changed or can change, which allows the compiler to generate more optimized code (3) where widget boundaries exist (treating lambdas as composable functions), allowing for more granular updates to occur. Obviously there is a lot more detail, but that is a topic for another day. @Shabinder Singh It's an interesting project, but I have nothing to add beyond what Google has already said publicly. My team spends most of our day thinking about Android - an operating system that is actually being used by real users 😉
d
@jim, thanks. It'll be a great read. Is the whole Compose compiler located in this directory? https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/c[…]d/src/main/java/androidx/compose/compiler/plugins/kotlin And looks like
ComposableFunctionBodyTransformer.kt
is the place where most of optimizations happen, am I right?
j
Many of the optimizations are more architectural (eg. syntax decisions impact allocations and widget boundaries, etc). But yes, you're digging in the right places.
🙏 1