Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporting web Worker and OffscreenCanvas use-cases #351

Open
fpapado opened this issue Mar 24, 2024 · 0 comments
Open

Supporting web Worker and OffscreenCanvas use-cases #351

fpapado opened this issue Mar 24, 2024 · 0 comments

Comments

@fpapado
Copy link

fpapado commented Mar 24, 2024

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:

  • Usage of instanceof HTMLCanvasElement comparisons
  • Feature detection via document.createElement
  • Access to document
  • Access to the DOM canvas in order to measure the DPR and width/height for resizeDrawingSurfaceToCanvas

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)

  • Browser: Chrome 122 Stable
  • OS: macOS 14.3.1
  • NPM Version: N/A (pnpm 8.15.3)

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 😇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant