Hi, I was testing the recompositions in my compose...
# compose
a
Hi, I was testing the recompositions in my compose multi platform screens, I noticed something, for some reason when using "Button" the recomposition counter goes absolutely crazy, with "TextButton" it does not, I am pretty sure this is a bug, Can someone test and confirm? I am on CMP 1.7.1 and compose android 1.7.5
Here is the layout inspector showing the difference between
Copy code
LazyColumn {
    item {
        if (uiState.isLoading) {
            CircularProgressIndicator()
        }
    }
    item {
        Button(onClick = onCreateClick) {
            Text(text = "Normal button")
        }
    }

    item {
        TextButton(
            onClick = onCreateClick,
            colors = ButtonDefaults.buttonColors()
        ) {
            Text(text = "TextButton with defaults of button colors ")
        }
    }
    item {
        TextButton(onClick = onCreateClick) {
            Text(text = "TextButton")
        }
    }
}
s
Does it behave the same when not in a lazy list? Does it behave the same when you are not sharing the same lambda of
onCreateClick
between the two buttons? Also, how is that lambda created? Does it behave the same when you do not pass in a lambda at all?
a
Yes for some reason those do not affect this at all, I just created an empty template and I am not able to reproduce
I have to look into what is special about this
s
Might be re-creating the lambda completely every time for some reason. Do you by any chance know if you are in a version which has strong skipping mode on or not? Does your lambda capture any non-stable parameters? If you could get a minimal repro of this I would be interested to see it, full code included.
a
Yes sure I can share the repo and have you look at the code, but I am not able to reproduce rn, i will try to remove as much code as possible
👍 1
I literally removed all of the code
it still persists
empty lambdas empty everything
s
Could you remove the scaffold as well?
a
I did, no difference
Copy code
agp = "8.7.2"
kotlin = "2.1.0-RC"
compose-plugin = "1.7.1"
compose-android = "1.7.5"
ksp = "2.1.0-RC-1.0.27"

androidx-lifecycle = "2.8.4"
androidx-navigation = "2.8.0-alpha10"

kotlinx-serialization-json = "1.7.3"
kotlinx-coroutines = "1.9.0"
kotlinx-datetime = "0.6.0"

koin-bom = "4.0.0"
ktor-bom = "3.0.1"
tried with stable kotlin version as well same result
s
So, when you hover over it, the interaction which adds the ripple effect makes it recompose a lot without it skipping it seems like?
a
Yep, pretty much insets also
basically anything that would skip otherwise
s
If you pass in a null indication (is that possible in the m3 Button?) does it stop the recompositions?
a
I can try
No thats not possible to add it seems
you cant change the interaction source
interactionSource: MutableInteractionSource? = null,
its basicallly null already
If you pass in a real implementation which does nothing, perhaps that would work
Something like
Copy code
object : MutableInteractionSource {
  override val interactions: Flow<Interaction>
    get() = emptyFlow()

  override suspend fun emit(interaction: Interaction) {
  }

  override fun tryEmit(interaction: Interaction): Boolean {
    return false
  }
}
a
Copy code
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
    Column {
        val interactionSource = remember { MutableInteractionSource() }
        Button(onClick = {}, interactionSource = interactionSource) {
            Text("Normal Button")
        }
        TextButton(onClick = {}, colors = ButtonDefaults.buttonColors()) {
            Text("Text Button (Button Defaults)")
        }
        TextButton(onClick = {}) {
            Text("Text Button")
        }
    }
}
no difference still
you can checkout the recomposition branch
i removed all the other code
s
this
Copy code
val interactionSource = remember { MutableInteractionSource() }
Will still have a real interaction source which gives the ripple. I was thinking of using this https://kotlinlang.slack.com/archives/CJLTWPH7S/p1731626195547829?thread_ts=1731623260.278379&amp;cid=CJLTWPH7S so that there's no interactions going through, so hopefully also no ripple. Then I'd check if there are still recompositions happening
👍 1
a
Yes, it seems to solve the issue
Its not recomposing anymore
Screen Recording 2024-11-15 at 00.31.59.mov
The ripple seems to be the problem here
s
Interesting. I wonder if that's just expected, or if the ripple should be able to re-draw without recomposing. I actually don't know how the ripple implementation works. Inside your MaterialTheme, are you passing anything to the
LocalIndication
composition local? I think there was some migration to be done sometime recently which may have been done to introduce a more efficient ripple effect?
a
I am pretty sure it should skip, it skips for textbutton
with the defaults of button
even if it intentionally recomposes, the counter is way to high
I am not passing anything to MaterialTheme
its the default implementation
s
Alright 👍 If you feel like you'd like an explanation for this, it's worth filing a bug report to get an official answer I'd say.
a
I cant figure out what exactly is special about this project that is causing this
I would file a report but I cant reproduce in an android project
or my other CMP Project wich has the exact same setup
s
Could it be an old m3 dependency which does not have some fix which might have been introduced later about this
a
@Stylianos Gakis Downgrading to CMP 1.7.0 also fixes the issue.
👍 1
but had to clean build
There is probably WIP in migrating these new Ripple APIs
s
Consider still filing a report since you got a repro in your project, this doesn't look correct / good