Compose phases and performance
Stay organized with collections
Save and categorize content based on your preferences.
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.
Compose can intelligently skip any of those phases if they aren't needed. For
example, suppose a single graphic element swaps between two icons of the same
size. Since this element isn't changing size, and no elements of the UI tree are
being added or removed, Compose can skip over the composition and layout phases
and redraw this one element.
However, coding mistakes can make it hard for Compose to know which phases it
can safely skip, in which case Compose runs all three phases, which can slow
down your UI. So, many of the performance best practices are to help Compose
skip the phases it doesn't need to do.
For more information, see the Jetpack Compose Phases guide.
General principles
There are a couple of broad principles to follow that can improve performance in
general:
- Whenever possible, move calculations out of your composable functions.
Composable functions might need to be rerun whenever the UI changes. Any
code you put in the composable gets re-executed, potentially for every frame
of an animation. Limit the composable's code to only what it needs to build
the UI.
- Defer state reads for as long as possible. By moving state reading to a
child composable or a later phase, you can minimize recomposition or skip
the composition phase entirely. You can do this by passing lambda functions
instead of the state value for frequently changing state and by preferring
lambda-based modifiers when you pass in frequently changing state. You can
see an example of this technique in the Defer reads as long as possible
section of Follow best practices.
Additional Resources
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2024-04-11 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-04-11 UTC."],[],[],null,["# Compose phases and performance\n\nWhen Compose updates a frame, it goes through three phases:\n\n- **Composition:** Compose determines *what* to show. It runs composable functions and builds the UI tree.\n- **Layout:** Compose determines the size and placement of each element in the UI tree.\n- **Drawing:** Compose actually *renders* the individual UI elements.\n\nCompose can intelligently skip any of those phases if they aren't needed. For\nexample, suppose a single graphic element swaps between two icons of the same\nsize. Since this element isn't changing size, and no elements of the UI tree are\nbeing added or removed, Compose can skip over the composition and layout phases\nand redraw this one element.\n\nHowever, coding mistakes can make it hard for Compose to know which phases it\ncan safely skip, in which case Compose runs all three phases, which can slow\ndown your UI. So, many of the performance best practices are to help Compose\nskip the phases it doesn't need to do.\n\nFor more information, see the [Jetpack Compose Phases](/develop/ui/compose/phases) guide.\n\nGeneral principles\n------------------\n\nThere are a couple of broad principles to follow that can improve performance in\ngeneral:\n\n- **Whenever possible, move calculations out of your composable functions.** Composable functions might need to be rerun whenever the UI changes. Any code you put in the composable gets re-executed, potentially for every frame of an animation. Limit the composable's code to only what it needs to build the UI.\n- **Defer state reads for as long as possible.** By moving state reading to a child composable or a later phase, you can minimize recomposition or skip the composition phase entirely. You can do this by passing lambda functions instead of the state value for frequently changing state and by preferring lambda-based modifiers when you pass in frequently changing state. You can see an example of this technique in the [Defer reads as long as possible](/develop/ui/compose/performance/bestpractices#defer-reads) section of [Follow best practices](/develop/ui/compose/performance/bestpractices).\n\nAdditional Resources\n--------------------\n\n- **[App performance guide](/topic/performance/overview)**: Discover best practices, libraries, and tools to improve performance on Android.\n- **[Inspect Performance](/topic/performance/inspecting-overview):** Inspect app performance.\n- **[Benchmarking](/topic/performance/benchmarking/benchmarking-overview):** Benchmark app performance.\n- **[App startup](/topic/performance/appstartup/analysis-optimization):** Optimize app startup.\n- **[Baseline profiles](/baseline-profiles):** Understand baseline profiles."]]