https://kotlinlang.org logo
#webassembly
Title
# webassembly
b

bashor

11/03/2023, 2:56 PM
Compose for Web artifacts for Kotlin/Wasm compatible with 1.9.20-RC2+
Copy code
Compose Multiplatform 1.5.10-dev-wasm02
Compose Compiler      1.5.3
🎉 10
🚀 1
p

Pablichjenkov

11/03/2023, 3:17 PM
I started working on a pet project using compose-web, I am ok only using chrome. Is it ok if I change my target from JS(IR) to wasm, or there are still not supported core libraries. Can we have not supported yet core libraries list?
o

Oleksandr Karpovich [JB]

11/03/2023, 8:13 PM
p

Pablichjenkov

11/03/2023, 8:39 PM
Well, that's right. It seems that I am covered, just need the basics for a json serialized server request.
👍 1
o

Oliver.O

11/06/2023, 7:15 PM
Kotlin 1.9.20 + Compose Multiplatform 1.5.10-dev-wasm02: Compose Web/Wasm performance now at 200% 🚀 of Web/Js. At least as seen by https://github.com/OliverO2/compose-counting-grid
🚀 18
kodee excited 10
K 10
b

bashor

11/06/2023, 7:17 PM
@Oliver.O Just to make sure — you mean wasm version is 2 times faster, right?
o

Oliver.O

11/06/2023, 7:22 PM
That's exactly what I mean. And no exceptions this time. Great work! 🚀🚀👏
b

bashor

11/06/2023, 7:23 PM
👍 Great! Thanks for sharing!
o

Oliver.O

11/06/2023, 7:23 PM
Thanks for accomplishing!
r

Robert Jaros

11/06/2023, 8:57 PM
Not so great in my tests, unfortunately. JS is still almost 2x faster for me. And I'm still hoping to see this fixed: https://issuetracker.google.com/issues/246751843 , because adding large number of nodes takes forever on both js and wasm.
o

Oliver.O

11/06/2023, 9:41 PM
I had observed JS being faster once, when animations were turned on. If you're seeing JS being consistently faster, that seems strange. Any idea why that could be the case? Could you cross-check, running my project on your machine?
r

Robert Jaros

11/06/2023, 9:43 PM
I'm running tests with my project, which operates on DOM nodes and uses lots of JS interop. I suppose that can make wasm target slower than just plain JS.
o

Oliver.O

11/06/2023, 9:49 PM
That seems entirely plausible. DOM manipulation speed is probably not something the Wasm infrastructure can influence. JS interop may also offer limited potential for optimizations outside the host environment (browser engine). What I found somewhat impressive is that I'm seeing the above improvements by switching just the Compose side of things between JS and Wasm. (The entire work of drawing stuff is handled by – supposedly – the same Wasm-compiled Skiko/Skia library in both cases.)
3
r

Robert Jaros

11/06/2023, 9:57 PM
I've tried running your project and it seems JS is faster for me.
I've tested with Chrome 120 on Linux
o

Oleksandr Karpovich [JB]

11/06/2023, 9:58 PM
Just a note: it's worth to try a production distribution
r

Robert Jaros

11/06/2023, 9:58 PM
25x25
And I have about 60 fps with JS and 25 fps with wasm
o

Oliver.O

11/06/2023, 10:00 PM
Did you run it via the invocations in the README (directly clickable in IntelliJ IDEA)?
r

Robert Jaros

11/06/2023, 10:01 PM
I've executed the commands from README directly from the command line
o

Oliver.O

11/06/2023, 10:01 PM
Let me also try command line. (I'm using Brave as of Chrome 119 BTW.)
o

Oleksandr Karpovich [JB]

11/06/2023, 10:03 PM
Robert, for your project you might want to try with binaryen applied to see if it makes any difference https://github.com/OliverO2/compose-counting-grid/blob/master/build.gradle.kts#L64 (afaik you use compose runtime, so binaryen might improve things)
r

Robert Jaros

11/06/2023, 10:08 PM
I've tried in Firefox nightly 119 and the results are a bit different. JS ~ 40fps and Wasm just a few fps faster (~45fps).
o

Oliver.O

11/06/2023, 10:20 PM
Copy code
compose-counting-grid, default configuration (no animations, no highlighting, etc.)
Intel(R) Xeon(R) CPU E3-1225 v5 @ 3.30GHz

25x25 Js:   48 FPS
25x25 Wasm: 60 FPS (limited by display frame rate)

50x50 Js:   16 FPS
50x50 Wasm: 31 FPS
b

bashor

11/06/2023, 10:20 PM
@Robert Jaros have looked on performance snapshots for your cases?
r

Robert Jaros

11/06/2023, 10:31 PM
@Oleksandr Karpovich [JB] applying binaryen helps just a little bit, but thanks for the tip (didn't know about this option).
Adding 5000 DOM nodes takes about 1m15s with wasm and about 50s with JS (Firefox 119). Still this is a horrible result 😉 , because JS frameworks do the same thing instantaneously. Definitely a corner case for compose runtime.
b

bashor

11/06/2023, 10:34 PM
I’d also look at other browsers
and performance snapshots
o

Oliver.O

11/06/2023, 10:39 PM
Getting the same results as above with Chrome 119. Noticed that displayed FPS go south when I have the dev tools open (even if it's just a mostly idle console display).
1
r

Robert Jaros

11/06/2023, 10:41 PM
What OS do you use?
o

Oliver.O

11/06/2023, 10:42 PM
Ubuntu 20.04.6 LTS
b

bashor

11/06/2023, 10:44 PM
Yeah, opening devtools may lead to regression
some of them switch immediately to version generated by baseline compiler or even worse to interpreter
some of them switches only when you open specific views
o

Oliver.O

11/06/2023, 10:52 PM
Crazy stuff, always good for some surprises. Seems to work reasonably well though whenever I do a performance recording. All CPU-bound, Color.kt, Path.kt, FontWeight.kt etc. is where most of the time is spend. Seems like the usual suspects to me given that the app just renders text in its cell grid.
r

Robert Jaros

11/06/2023, 10:53 PM
It's late and I'm lost in my results ;]
Now I see 60fps on my chrome with both js and wasm ;)
o

Oliver.O

11/06/2023, 10:55 PM
That means you've hit your display limit. Use a larger grid. But first, get some well-deserved sleep, then come back and enjoy the world-class support in this theater! 😊
1
r

Robert Jaros

11/06/2023, 10:55 PM
And wasm is indeed faster on 50x50 grid.
50fps with wasm vs. 23fps with js
So after hour of testing I confirm your results! :)
👍 1
o

Oliver.O

11/06/2023, 11:01 PM
Don't worry too much. I've been there before, hit by inconsistent results. Could also be some background process I wasn't aware of at the time and didn't check machine load. As long as we come to some evidence-based consensus, this is how science works, and this is why science works! ❤️
r

Robert Jaros

11/06/2023, 11:09 PM
Now in chrome even my project runs faster with wasm. Not so spectacular difference but it's like 30sec. js vs. 25sec. wasm. So Kotlin/Wasm is definitely on the right path 🙂
👍 1
🤞 1
👌 1
o

Oliver.O

11/06/2023, 11:32 PM
Ah, and before I call it a day just one more hint: The FPS reported by compose-counting-grid are not necessarily the "real" FPS as rendered. The way
withFrameNanos
is used to calculate displayed FPS has its limitations and cannot be used as some absolute performance indicator. For example, if animations are turned on, the displayed FPS rate does down, although the digit images move very smoothly, which creates the visual impression of much higher frame rates than displayed. Nonetheless, displayed rates seem to be useful for directly comparing the same type of rendering between different targets.
f

franztesca

11/07/2023, 9:19 AM
Is it likely that Compose+WASM is also 2x faster than react(+dom)? 🤔
r

Robert Jaros

11/07/2023, 10:01 AM
Definitely not.
Compose runtime has still major performance issues.
o

Oliver.O

11/07/2023, 10:27 AM
I’d say it’s impossible to answer this question correctly without considering the precise use case. Firstly, we’re talking Compose on Canvas here, right? The DOM isn’t always fast (giant tables become glacially slow). React VDOM management and diffing takes time, so do Compose slot table operations. If specific things are fast on a micro level, better macro-level APIs like lazy layouts might still result in much better performance. I always advise folks to do their own prototyping and benchmarking in order to actually measure what’s relevant for the specific use case.
One more thing: Applying the binaryen options below can improve Wasm speed by another 20% and reduce compressed
app.wasm
size by 24% (473 kB instead of 623 kB). The more aggressive optimization takes longer, of course.
Copy code
applyBinaryen {
    binaryenArgs = mutableListOf(
        "--enable-nontrapping-float-to-int",
        "--enable-gc",
        "--enable-reference-types",
        "--enable-exception-handling",
        "--enable-bulk-memory",
        "--inline-functions-with-loops",
        "--traps-never-happen",
        "--fast-math",
        "--closed-world",
        "--metrics",
        "-O3", "--gufa", "--metrics",
        "-O3", "--gufa", "--metrics",
        "-O3", "--gufa", "--metrics",
    )
}
👍 2
b

bashor

11/07/2023, 4:54 PM
Have you tested it on compsoe example?
--closed-world
used to be incompatible with compose examples
o

Oliver.O

11/07/2023, 4:55 PM
I have tested it on my usual suspect: https://github.com/OliverO2/compose-counting-grid
🤔 1
And yes, I do not claim to know exactly what I'm doing, as I haven't researched the implications thoroughly. The doc says that
--closed-world
is required for
--gufa
, so I thought I'd just give it a try.
r

Robert Jaros

11/07/2023, 5:11 PM
These options work great for my compose project as well (~20% faster, ~30% less size).
🔥 2
🙂 1
b

bashor

11/07/2023, 5:14 PM
Interesting, need to recheck that and update defaults. Thank you, folks, for checking that.
👍 1
o

Oliver.O

11/07/2023, 5:17 PM
Cool. I guess that was mostly due to luck. Sort of fuzzying optimization strategies.
BTW: Updating a 50x50 grid will slow down somewhat over time. As I did not notice any memory-related issues, my guess is that this is due to increasing drawing intensity. As the grid populates, more cells become non-empty, more text is required to be redrawn on each frame. (Unlike the browser with DOM, Compose still redraws the entire canvas per frame.)
🚀 compose-counting-grid, 50x50 grid, default configuration (no animations, no highlighting), windows sized consistently, being just large enough to accommodate the grid, VMs warmed up over 6000+ seconds: • Chrome/Wasm (aggressively optimized): 32 FPS (84% of desktop performance!) • Desktop/JVM: 38 FPS What if we used Skiko with equally aggressive optimization? Could it be that K/Wasm on Chrome is already at "native-like" speed? 🏅
🚀 2
🤔 2
Tried to reproduce on a MacBook Air M2. Too fast: Always hitting the display sync rate if used without animations. With animations enabled, on the MacBook Chrome/Wasm performs at 40-50% the speed of the JVM. On my slower Ubuntu machine Chrome/Wasm performs at 80% of the JVM. (However, with animations turned on, I don't trust the reported FPS counts, as I am not convinced that I am sufficiently aware of side effects affecting
withFrameNanos
.)
r

Robert Jaros

11/17/2023, 9:38 AM
Can we use available serialization/coroutines/compose artifacts with Kotlin 2.0.0-Beta1 ?
o

Oleksandr Karpovich [JB]

11/17/2023, 9:39 AM
I tried kotlin 2.0.0-Beta1 with compose examples. Only a new compose compiler plugin is required: https://github.com/Kotlin/kotlin-wasm-examples/pull/37
🙏 1
12 Views