Log Compose Compositions
The easiest way to debug recompositions is to use good ol' log statements to see which composables functions are being called and the frequency with which they are being called. This is really obvious but there's some nuance to it - we want to trigger these log statements only when recompositions are happening. This sounds like the perfect use case for SideEffect, a composable function that is reinvoked on every successful composition (& recomposition).
Here's this helper function in action -
@Composable
fun MyComponent() {
val counter by remember { mutableStateOf(0) }
LogCompositions(TAG, "MyComposable function")
CustomText(
text = "Counter: $counter",
modifier = Modifier
.clickable {
counter++
},
)
}
@Composable
fun CustomText(
text: String,
modifier: Modifier = Modifier,
) {
LogCompositions(TAG, "CustomText function")
Text(
text = text,
modifier = modifier.padding(32.dp),
style = TextStyle(
fontSize = 20.sp,
textDecoration = TextDecoration.Underline,
fontFamily = FontFamily.Monospace
)
)
}
On running this example, we notice that both MyComponent
& CustomText
are recomposed every time the value of the counter changes.
// Full credit for this snippet goes to Sean McQuillan - https://twitter.com/objcode | |
class Ref(var value: Int) | |
// Note the inline function below which ensures that this function is essentially | |
// copied at the call site to ensure that its logging only recompositions from the | |
// original call site. | |
@Composable | |
inline fun LogCompositions(tag: String, msg: String) { | |
if (BuildConfig.DEBUG) { | |
val ref = remember { Ref(0) } | |
SideEffect { ref.value++ } | |
Log.d(tag, "Compositions: $msg ${ref.value}") | |
} | |
} |
Maker OS is an all-in-one productivity system for developers
I built Maker OS to track, manage & organize my life. Now you can do it too!