Table of contents
Open Table of contents
Introduction
In modern Android development, Jetpack Compose is introduced as a declarative UI toolkit for building native UIs. Unlike traditional XML layouts, Compose simplifies how developers write and maintain UIs by using less code, offering powerful tools, and intuitive Kotlin APIs. In Compose, each UI element is defined as a @Composable
function. Hereโs an example showing how to display a greeting message on the UI:
@Composable
fun Greeting(name: String) {
Text("Hello $name")
}
What are Compose Phases?
Before diving into recomposition, itโs helpful to understand the Compose phases involved in rendering UI elements. Jetpack Compose follows three primary phases: Composition
, Layout
, and Drawing
. The order typically flows in one direction to render a frame on the UI. However, there are exceptions, such as BoxWithConstraints
, LazyColumn
, and LazyRow
, where the composition of children depends on the parentโs layout phase.
To visualize the phases, we can add debug logs in the modifier to track each phaseโs process:
@Composable
fun Greeting(name: String) {
Log.d("Greeting", "Composition Phase ๐")
Text(
text = "Hello $name",
modifier = Modifier
.onPlaced {
Log.d("Greeting", "Layout Phase - Placement ๐")
}
.onSizeChanged {
Log.d("Greeting", "Layout Phase - Measurement ๐")
}
.drawBehind {
Log.d("Greeting", "Drawing Phase ๐ผ๏ธ")
}
)
}
๐จ๏ธ Result logs:
D Composition Phase ๐
D Layout Phase - Measurement ๐
D Layout Phase - Placement ๐
D Drawing Phase ๐ผ๏ธ
Composition
The Composition
phase is where the UI layout hierarchy is generated in a tree structure. The parent layout sits on top, and all child composables nested within a container layout occupy the same node level.
Layout
During the Layout phase, the tree is traversed through:
Measurement
: Each child nodeโs size(width/height)
is measured and reported back to the parent node, which then calculates its own size based on the childrenโs dimensions.Placement
: After measurement, the nodeโs coordinates(x, y)
are determined to place the element in 2D space.
In this phase, each node is visited only once. This single pass enhances performance, as the time spent traversing the UI tree increases linearly with node count. Visiting nodes multiple times would otherwise increase traversal time exponentially.
Drawing
The final phase, Drawing, traverses the node tree from top to bottom, rendering each node on the screen. Using the previous example, the tree content is drawn as follows:
- The
Row
draws its content, like a background color. - The
Image
is rendered. - The
Column
is drawn. - The first and second
Text
elements are rendered in sequence.
What is Recomposition?
Recomposition in Jetpack Compose is the process of re-running composition when input states change. Depending on the result, Compose may re-run the layout and drawing phases. However, if content, size, and layout remain unchanged, these phases might be skipped, enhancing efficiency. When the state value changes, Compose schedules the layout phase and may trigger the drawing phase if size or position changes are detected.
Upcoming post
Since these phases consume system resources and can impact performance or battery life, Compose skips redundant runs of composable functions, reusing previous results to minimize work. In a future article, weโll explore best practices for optimizing Compose performance. See ya ๐
Reference
https://developer.android.com/develop/ui/compose/phases https://developer.android.com/develop/ui/compose/lifecycle