Skip to content

Understanding Compose Phases and Recomposition

Published:ย atย 02:00 PM (3 min read)

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?

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.

Composition

Layout

During the Layout phase, the tree is traversed through:

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.

Layout

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:

Drawing

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.

Recomposition

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


Previous Post
[Webinar GDG on Campus UTH] Native vs Cross-Platform in Mobile App Development ๐Ÿš€
Next Post
Modern libraries to build Android application