Jetpack Compose6 min read

Compose Performance: Why Your UI Re-renders Too Much 🔄⚡

Nov 24, 2025By Divya

Jetpack Compose is powerful - but if you've ever wondered "why is my UI recomposing so often?" you're not alone. Most performance issues come down to a few simple patterns that accidentally trigger unnecessary renders.

Here's the bite-sized breakdown 👇

🔥 1. Unstable Parameters = Extra Recomposition

If you pass objects that change on every call (lists, lambdas, data classes without @Stable/@Immutable), Compose considers them new every time.

@Composable
fun MyList(items: List<String>) { ... }  // if items changes → full recompose

Fix:

  • ✓ Use remember for state holders
  • ✓ Prefer immutable data
  • ✓ Mark stable models when possible

🔥 2. State in the Wrong Place

If a parent holds all the state, the entire child tree re-renders when anything changes.

var text by remember { mutableStateOf("") }
Parent(text) // re-renders whole subtree

Fix:

  • ✓ Hoist only the state you need
  • ✓ Keep local UI-only state in the child

🔥 3. Derived Values Calculated Every Time

If you compute expensive logic inside a composable without memoizing it, you force recompositions to work harder.

val filtered = items.filter { ... }  // recalculated on every recompose

Fix:

Use derivedStateOf for computed state:

val filtered by remember { derivedStateOf { items.filter { ... } } }

🔥 4. Missing key in Lazy Lists

If Compose can't uniquely identify list items, it re-renders more than necessary — sometimes the whole list.

items(items) { item -> ... } // bad

Fix:

Specify a stable key:

items(items, key = { it.id }) { item -> ... }

🔥 5. Recreating Objects in Compose

If you recreate a coroutine scope, animation, or modifier each time, you trigger extra recomposition or work.

Fix:

  • ✓ Use rememberCoroutineScope()
  • ✓ Store animations in remember
  • ✓ Avoid rebuilding heavyweight modifiers

🪄 TL;DR

If your Compose UI re-renders too much, check for:

  • ✔ Unstable parameters
  • ✔ State lifted too high
  • ✔ Missing remember / derivedStateOf
  • ✔ LazyList without keys
  • ✔ Objects recreated every frame

A few tweaks = a massive performance upgrade.