rive-app / rive-wasm

Wasm/JS runtime for Rive
MIT License
660 stars 46 forks source link

Supporting web Worker and OffscreenCanvas use-cases #351

Open fpapado opened 3 months ago

fpapado commented 3 months ago

Description

Hi folks, and thank you for making Rive šŸ‘‹

Long story short: I would like to use rive-app/canvas (or the underlying rive.js) in a web worker environment, backed by an OffscreenCanvas (transferred from the main thread via transferControlToOffscreen).

There are some small changes that could facilitate that, but also some larger questions around supporting this out-of-the-box, or via an additional library layer.

Context

I have been looking at Rive in the context of a large frontend application, which has a lot of work going in the main thread. While Rive itself is very fast, the animations can still stutter if the main thread is taxed.

There are many ways to work with this, largely outside of Rive's domain. However, one of the exciting things about Rive, for me, is that its cavnas-backed renderers are very robust, and that the types support OffscreenCanvas. Moving the animations to an OffscreenCanvas in a worker would allow the animations to keep being snappy, and alleviate some of the work on the main thread.

To be clear: I think optimising the main thread is a good idea, but many contemporary frontend applications are still largely on the main thread šŸ˜© Thus, I think this would be a practical win for many applications.

This all led me to exploring the space of running @rive-app/canvas (and rive.js specifically) inside a web worker. I kept it quite use-case specific, mostly to see if it is possible.

I ran into some papercuts along the way, and I took some time to document those, as well as future expansion points. I was a bit surprised that there are not many resources around this on the web!

Provide a Repro

A demo and a longer description is available on this repository. There is a patch in the patches directory, with the minimum to prevent throwing in a web worker.

Source .riv/.rev file

Expected behavior

It would be nice if, by default, @rive-app/canvas, or the underlying rive.js bindings supported web workers with OffscreenCanvas.

There are four main things that I ran into:

I think the first three are fixable by doing any feature-detection via OffscreenCanvas first (since it is available in both the window and workers scopes). However, browser support might make that check more complicated for the library.

The last issue is a bit more complex. A mechanism to provide width and height manually (and update them) would allow callers to build custom logic for resizeDrawingSurfaceToCanvas (e.g. passing messages to/from the main thread). There is a comment in the docs that hints this might be in the works already šŸ‘€

I have also added notes about what a potential @rive-app/canvas-worker could look like, that would facilitate these cases, and some additional coordination.

Screenshots

Browser & Versions (please complete the following information)

Additional context

These are just ideas and suggestions. I think it's possible to work around these for use-case specific things, but I am interested in hearing if the Rive team has considered the web worker use-case, and whether there are plans for it in the future.

Feel free to close this issue or ask for more information šŸ˜‡