Understanding Recomposition Overhead in Compose
Jetpack Compose transforms declarative UI development, but unnecessary recompositions across nested composable trees can cause noticeable frame stutter (jank), especially during rapid scroll events in LazyColumn.
1. Use derivedStateOf to Buffer Frequent State Updates
When listening to rapid scroll position changes, never trigger recompositions on every pixel offset:
// BAD: Recomposes on every single scroll pixel
val isScrolled = scrollState.firstVisibleItemIndex > 0
// GOOD: Recomposes only when the boolean condition flips
val showScrollToTop by remember {
derivedStateOf { scrollState.firstVisibleItemIndex > 0 }
}
2. Defer State Reads with Lambda Modifiers
Pass state readers directly into layout/draw phases to bypass the composition phase entirely:
// BAD: Triggers composition on every offset change
Box(modifier = Modifier.offset(y = animatedOffset.dp))
// GOOD: Bypasses composition and applies directly to layout/draw phase
Box(modifier = Modifier.offset { IntOffset(0, animatedOffset.value.roundToInt()) })
3. Mark Data Models as @Immutable or @Stable
Classes defined in external modules without Compose compiler plugins default to unstable, forcing recomposition even when properties remain identical. Annotate them with @Immutable to enable smart skipping.
In-Article Sponsored Content
Suggested Engineering Guides
View All Guides (22+)
Recommended For You
Ads by Google
Comments (0)
No comments yet. Share your thoughts below!
Leave a Comment
Share your thoughts or questions. Your email address remains private.