Hi everyone! Did anybody manage to do computation ...
# javascript
c
Hi everyone! Did anybody manage to do computation heavy work inside web workers? How did you do it? I'm trying to put deserialization (kotlinx serialization) work inside a web worker to not block the main thread, and I'm curious if somebody has experience with it or if there is any already existing solution for it. Or maybe somebody knows a better solution for it :D
d
Hello! I actually support this in Kobweb (https://kobweb.varabyte.com/docs/concepts/foundation/workers), but give me a bit and I'll try to recall the relevant parts if you want to do this on your own
Writing a web worker is basically like writing a normal web script, except you don't have access to the DOM (attempting to access
window
throws an exception)
There is a global called "self" which in a normal script is type Window (see also: https://developer.mozilla.org/en-US/docs/Web/API/Window/self) but in a worker is type DedicatedWorkerGlobalScope. Which you can use as part of the message passing between scripts.
Finally, you want to familiarize yourself with the Worker API itself
So your worker code should be in a different module from your main web script. It should also be set up with KJS in a way that generates a javascript file. In your final site, you should copy that JS file into a directory that will get served by your web host. Then in your main script, you create a Worker instance, passing in the path to that target JS file.
That is the high level basics -- and based on what you wrote, you may already have done this.
t
So your worker code should be in a different module from your main web script
If you don't have plugin 😉
d
Which plugin?
t
With Seskar you can write workers in same project.
But it won't work with serialization, because you can't transfer Kotlin classes between Window in Worker
d
Oh very interesting, there's another option. How do you set up dependencies in the worker you don't want in the main script?
t
If it's required in your case you hide Worker logic in separate subproject.
d
I'm assuming the plugin ultimately creates two separate JS files?
One of the issues with Kotlin/JS web workers is that BOTH your main script and the worker script need their own (potentially tree shaken) copy of the Kotlin runtime.
Does Seskar improve that situation?
t
It requires
per-file
compilation
👍 1
And for worker it creates additional JS file
d
Just to finish up my original thoughts, the last thing I wanted to mention is there is a concept called "Transferables", which is a way to send large objects (probably in most realistic cases, a large file or bitmap image) from the main script to your worker script. I can jump into that more if this is relevant to you, but Kobweb handles that here (see also my own concept called Attachments, which is transferables plus a bit of other stuff)
c
Thank you @David Herman I will check!
Copy code
That is the high level basics -- and based on what you wrote, you may already have done this.
Yes I have the same approach but struggling a little bit with the copy-ing part part since I don't have much experience with web. But its good to know that I'm on a good track then. It was also a question for me if I will be able to pass deserialized kotlin objects or types from/to web workers but as I understood, its possible.
👍 1
d
Look up Transferable and Clonable docs on MDN, it should give you the idea of the kind of raw objects you are allowed to pass between main script - workers
👍 1
Good luck and feel free to ask more questions if you run into any!
c
Thanks! Will do! :D
t
How much data do you plan to deserialize (or serialize)? I'm just curious about the need to move it into a worker. Another solution would be to use a binary protocol such as protobuf.
👍 1
c
@Tóth István Zoltán We have huge backends sometimes with big responses that need to be deserialized, and with old devices it can take a relatively lot of time, which affects startup time. Even on Android we can feel that deserialization is computation-heavy for our devices.
Fortunatelly on others platforms we have more threads 😄
t
With JSON it can be problematic especially if you use datetime classes without optimization. I send out histories with tens of thousands of records and it is still quite fast. The difference between Json and protobuf is immense.
c
Agree. But isn't protobuf hard to debug? in case of deserializing BE response I think it can be a nightmare, no?
Anyway, for us its not a viable option
t
I’ve never had any problems with it.
You could try to use custom serializers if you use kotlinx.serialization. They can be much-much faster than the default ones.
👍 1