I've got <a little sample application> using compo...
# compose-desktop
a
I've got a little sample application using compose in WASM, and when it starts up I do some processing using coroutines on the Default dispatcher. On desktop it works properly, my loading spinner animates and the UI is responsive. On WASMjs it locks the UI until it's done. What's the deal with coroutines in WASM? Or threads in WASM in general I guess?
m
Same for Compose Web (JS)
a
Isn’t this because the browser is inherently single threaded? Offloading something to a separated coroutine will still cause it to be on the same thread. Since it is a CPU bound task it’ll block the Ui
o
readResourceBytes
is a suspend fun, under the hood it makes fetch (browser runs it in a worker). so 2 fetch requests do not block the thread. But depending on the size of those files and the applied processing after the fetch, it might take some time. yes, it's single threaded. Heavy processing better to run in a worker. (fetch + strings processing) And then to post the result back so Compose can use it.
a
hhmmm is there any way to write common code that would "do the right thing" for web?
what would be the right way to do a load & process and not stall the UI on web?
a
If it is a CPU bound task it would be with web workers. A shameless plug: https://avwie.github.io/multithreaded-web-applications-in-kotlin-with-web-workers
o
without web workers, I guess it might help to
yield()
from time to time in the loops (in fastForEach). But I'm not sure what part is the most heavy. If it's not the loop, but decodeToString or splitLines, then not sure where to put
yield
. Also to reduce the total waiting time, I think it might worth to make parallel fetch requests (currently they're consequent - readResourceBytes). Perhaps two Launched effects would do the job, or one Launched effect with two
scope.launch(Dispatchers.Default) { ... }
Using async { } - https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html
a
@Oleksandr Karpovich [JB] great, okay as a first measure I put a yield in the for each, and that largely solves the problem. however I could make this much more efficient, I'm going to try some of your other suggestions tonight
👍 1
splitLines
is probably causing a full re-allocation of the input? I'm guessing here, but it's probably not acting like a stream.