Web Worker Offscreen Canvas toBlob latency

119 views Asked by At

I have a hidden canvas in a react app that I send to a web worker using transferControlToOffscreen (code).

Everything is working, but after updating the canvas (fillRect for example) the worker signals the main thread using postMessage (code).

The main thread then converts the canvas toBlob and uploads it (code).

If I put the worker's postMessage inside a setTimeout callback for about 500ms everything works as expected. If I call postMessage immediately, the blob actually contains the canvas data before the update was made.

I don't really have any experience to base it on, but I'd have expected that the blob would immediately reflect the up-to-date canvas data. It feels like latency but react is also in the mix -- I just wouldn't have expected the render loop to affect a hidden the canvas contents.

Is the delay expected or am I overlooking something?

1

There are 1 answers

2
Kaiido On

Yes the delay is expected.
The placeholder canvas (the one that stays in the main thread) is updated with the OffscreenCanvas buffer only when the event-loop enters the "update the rendering" steps (basically when the requestAnimationFrame callbacks are executed).

So you'd have to wait for the next such rendering update in your worker before sending your message to the main thread. (Note that there used to be a commit() method, that's still specced, but which is going to be removed any time now).

But the best might actually be to convert your OffscreenCanvas from the Worker thread and send the Blob directly to the main thread.

// In your worker
const blob = await canvas.convertToBlob();
postMessage(blob);