I have developed a quite complex keyboard layout in Jetpack Compose. Initially, the layout works fine and animations run very smoothly when pressign the keys. Unfortunately, after a few recompositions due to events the animations and everything becomes very slow and laggy. I have tried to sample Jave Method calls and I can only see that some function take a lot longer than usual.
Edit:
I have been able to isolate the issue. I have discovered that the performance issue only appears in multi module projects. When I put the exact same compose code in the root app
module the issue disappears.
I have created a project that reproduces the issue:
If you want to reproduce the issue in the multi module project you have to switch between the categories multiple times and then everything becomes very laggy
Note: I know Jetpack Compose is still in alpha and this issue might be a bug in Jetpack Compose. But I want to make sure that it's not a bug of my code or a general limitation of Compose
Slow frame percentage: For compose-based layout, the slow frame rate came out to be 8.91% whereas it was 9.93% for XML-based layout. Like frozen frames, ~10 out of 100 frames would fall under the slow frame category for XML-based layout.
Compose 1.2 includes a number of updates for Compose on Phones, Tablets and Foldables - it contains new stable APIs graduated from being experimental, and supports newer versions of Kotlin. We've already updated our samples, codelabs, Accompanist library and MDC-Android Compose Theme Adapter to work with Compose 1.2.
A LazyColumn is a vertically scrolling list that only composes and lays out the currently visible items. It's similar to a Recyclerview in the classic Android View system.
mutableStateOf creates an observable MutableState<T> , which is an observable type integrated with the compose runtime. Any changes to value will schedule recomposition of any composable functions that read value . In the case of ExpandingCard , whenever expanded changes, it causes ExpandingCard to be recomposed.
We have just seen an approach to designing a scalable multi-module architecture for Android apps that use Jetpack Compose, including navigation. Below is the complete diagram that defines a structure of a single feature in the app using the described approach.
Jetpack Compose accelerates UI development and makes Android engineers more productive. However, adding a new tool to a project requires some consideration as it can affect the APK, and build and runtime performance. In this section, we compare how two different apps were impacted when adding or migrating to Jetpack Compose:
As discussed in Jetpack Compose Phases, when Compose updates a frame, it goes through three phases: Composition: Compose determines what to show –it runs composable functions and builds the UI tree. Layout: Compose determines the size and placement of each element in the UI tree. Drawing: Compose actually renders the individual UI elements.
Traditional ViewGroups have lots of expressiveness in their measure and layout APIs that make it easy to cause multiple layout passes. These multiple layout passes can cause exponential work if done at specific nested points in the view hierarchy. Jetpack Compose enforces a single layout pass for all layout composables via its API contract.
The solution is to use remember
composable for Keyboard
@Composable
to prevent layouts computation during recomposition.
val refs: List<List<Pair<Key, ConstrainedLayoutReference>>> =
remember {
keyboard.map { row ->
row.map {
it to createRef()
}
}
}
val modifier = remember { ... }
val modifierPressed = remember { ... }
Source code: https://github.com/dautovicharis/example_compose-keyboard-multimodule/commits/main
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With