I have a strange issue with wasmJs and compose run...
# webassembly
r
I have a strange issue with wasmJs and compose runtime. My project uses the same, common code to implement compose runtime applier to manage DOM nodes for both JS and WasmJS targets. And I have just noticed that my compose engine works differently in JS and WasmJS targets with exactly the same code. The difference is that wasmJs app triggers many more node removal calls when using some advanced composables (I'm porting lazy-layouts from OpenSavvy). The final recomposition effect is the same, but there are noticeable scrolling side effects. I was convinced compose runtime manages the tree with a strict algorithm. How it is possible that the same code triggers different composition effects? Could it be a bug in Kotlin/Wasm or Compose Wasm runtime implementation? Is there any way to debug this?
o
It should be the same. But since compose relies on equality checks and/or hashCodes, there can be some discrepancies. For example we need to fix indetityHashCode implementation in compose k/wasm. Do you have a minimal reproducer? Ideally we would have a test to compare this behaviour
r
I'll play a bit more with this and try to prepare something
🙏 1
I think I've found the source of the problem - it seems using a lambda as a key to
remember
works differently. On JS such key works correctly but on wasmJS it's not -
remember
is recalculated every time.
And the problem is not in
remember
but in the lambda itself.
This is the root cause of my problem: https://pl.kotl.in/2ON5oLhEK
On wasm the results are different. On other platforms are the same.
s
Compose relies on Kotlin in this instance to optimize lambdas to be a single instance, because it doesn't have captures Seems like this optimization is absent from wasmJs
o
I see. Thanks! That optimization is absent in k/js too. We enabled the similar optimization (for nomcomposable lambdas) in compose for kjs only. We can enable it for wasm too. Or would be better to have in k wasm directly
Do you have a snippet where this behaviour can be reproduced? I checked that the workaround on Compose side is enabled for both k/js and k/wasm. So I'd expect no difference in the behaviour.
r
As far as I understand the workaround focuses on recomposition optimization. But the problem I see is not about recomposition. It affects
remember()
key
parameter, when the
key
is a a
Pair
with a function component (and the
Pair
is initialized with a lambda).
The lambdas passed to the
key
parameter are equal on JS and on JS
remember()
works ok. But they are different on Wasm, and remember() re-runs the calculation.
In my opinion the problem is not really about compose, but about lambdas (in)equality in wasm (and wasm only).
o
in my understanding, Compose workaround should've done the following:
remember("foo" to { println("foo") } ) { ... }
->
Copy code
remember("foo" to remember { {println("foo")} } ) { ... }
Perhaps, there is something else involved too. Anyway, the issue is planned to be fixed in 2.0.0:Beta4 - https://youtrack.jetbrains.com/issue/KT-64803
❤️ 1
👍 1
🙏 1