compose-multiplatform icon indicating copy to clipboard operation
compose-multiplatform copied to clipboard

Recomposition happens when Compose code comes from a dependency module

Open bitspittle opened this issue 1 year ago • 2 comments

Please check out this project which demonstrates the issue:

https://github.com/DennisTsar/bug-reports/tree/kotlin/compose/recomposition-1

Copying the README from that project here:


Compose 1.6.0+ Recomposition Issue

  • Run ./gradlew app:jvmRun -DmainClass=MainKt or ./gradlew app:jsBrowserDevelopmentRun and enter text into the textfield. Observe that the first CustomRow does not recompose on button click, but the second does.
  • If contents of lib are moved to app, the issue goes away
  • JVM behavior has occurred since at least Compose 1.5.12/Kotlin 1.9.22
  • JS behavior began with Compose 1.6.0/Kotlin 1.9.22
  • Still present on both targets with Compose 1.6.11 & Kotlin 2.0.0

bitspittle avatar Jun 14 '24 04:06 bitspittle

Just to emphasize how problematic this bug potentially is, I added the following code to my local project (a web project built using Kobweb):

var msg by remember { mutableStateOf("") }
TextInput(msg, onTextChanged = { msg = it }, ...)

// Sibling element which should NOT be affected by text input changes
Row(horizontalArrangement = Arrangement.spacedBy(10.px)) {
    var recomposeCount by remember { mutableStateOf(0) }
    recomposeCount++
    Text("Recompose count: $recomposeCount (should stay at 1)")
}

I expected one extra recomposition per character I typed into my text box, which would already have been a little bad, but instead I got a case of infinite, non-ending recompositions! This would have been invisible waste if I hadn't surfaced them via a text element:

https://github.com/JetBrains/compose-multiplatform/assets/43705986/f783ef92-bb29-458d-9656-5e5c60da947a

Once I added the @Immutable annotation to the empty RowScope interface (as the repro project suggests as a possible fix), the recompositions stopped.

This is clearly not intended behavior; Compose should not be getting confused about the immutability of an empty interface.

bitspittle avatar Jun 17 '24 16:06 bitspittle

Does it behave differently on Android?

m-sasha avatar Jun 19 '24 13:06 m-sasha

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

okushnikov avatar Jul 14 '24 14:07 okushnikov