Transferables
Transferables are special objects which are allowed to be moved between threads, rather than copied.
Transferables are essentially a performance optimization. While serialization may work fine in most cases, it can cause a noticeable, even multi-second stutter for very sizable objects (like large bitmaps).
Transferables allow the developer to tell the browser that you want to take a large object and send it across threads rather than copy it. After a transferable operation is complete, the original value is considered dead in the thread sending it.
Not every object can be transferred. In order to constrain users from sending unsupported types, we require users create a Transferables
instance using a Transferables.Builder.
Unlike default JS APIs, which just send an array of transferables, we require the user to specify the name of each object, as an added layer of safety.
// Sender
worker.postMessage(message, Transferables { add("bitmap", bitmap) })
// Receiver
internal class TransferableWorkerFactory : WorkerFactory<String, String> {
override fun createStrategy(postOutput: OutputDispatcher<String> -> Unit) = WorkerStrategy<String> { input ->
val bitmap = transferables.getImageBitmap("bitmap")
...
}
override fun createIOSerializer() = createPassThroughSerializer()
}
Not every object in the web is transferable, so the add
methods and get
methods are appropriately typed to constraint what you can register and fetch.
Note that arrays are actually not transferable, but we add support for them here anyway, doing the conversion to their underlying ArrayBuffer
ourselves to avoid the users having to do a bunch of boilerplate.