Web (JS) Canvas vs WebGL

Canvas vs WebGL

Background

The JS/WASM runtime provides various packages which are published to npm. For simple usage and smaller package sizes, we recommend starting with @rive-app/canvas (more on that below). On the web, Rive offers the ability to use a backing CanvasRenderingContext2D context or WebGL context associated with a <canvas> element for rendering Rive animations.

Note: The high-level API and the logic for creating a Rive instance in your script remain the same for the @rive-app/webgl and @rive-app/canvas packages. That means if you decide one runtime package is better for your use case over the other, you only need to switch the dependency, but not the usage. See more below on each of the different runtimes for JS/WASM and when to use which package.

(Recommended) @rive-app/canvas

npm install @rive-app/canvas

An easy-to-use high-level Rive API using a backing CanvasRenderingContext2D renderer. This lets Rive use the browser's native high-level vector graphics renderer. Some benefits of this package:

  • Small download size without the bloat of a separate renderer dependency

  • Support for Rive Text

  • Great for displaying many animated canvases concurrently on the screen. This is ideal for when you want to render lists or grids of Rive animations on the screen, as there is no context limit by the browser (as opposed to WebGL)

  • Support for simple vector graphics animations and raster

  • Requests the Web Assembly (WASM) backing dependency for you

Want an even smaller Rive dependency that doesn't have all the bells/whistles? Consider using @rive-app/canvas-lite below 👇

@rive-app/canvas-lite

npm install @rive-app/canvas-lite

A smaller package than that of @rive-app/canvas with the same API and backing CanvasRenderingContext2D, but does not compile and build WASM with certain dependencies in order to keep the package size as small as possible.

This solution will be preferable if you do not have a need for the following features below:

  • Rive Text

    • If your Rive file may include Rive Text components, rendering the graphic should not cause any app errors, or cease to render. Rive Text will just not appear within the graphic

    • You can still make use of text within your graphic by importing text externally as SVG

@rive-app/webgl

An easy-to-use high-level Rive API using a WebGL2 context. Some benefits of this package:

  • Highest fidelity with edit-time experience.

  • Requests the Web Assembly (WASM) backing dependency for you

  • Currently uses Skia for rendering, but in a future major version release will be replaced with the new Rive Renderer

A note about WebGL: Most browsers limit the number of concurrent WebGL contexts by page/domain. Using Rive, this means that the browser limit impacts the number of new Rive({...}) instances created.

If you're planning on displaying Rive content in a list/grid or many times on the same page, it's up to you to manage the lifecycle of the provided context and canvas element. If you need to display many animations (i.e grids/lists), consider using the @rive-app/canvas package which uses the CanvasRenderingContext2D renderer and does not have a context limitation, or consider the @rive-app/webgl-advanced package, which will allow you to display multiple Rive graphics on one canvas with full control over the render loop.

It is recommended to set the useOffscreenRenderer: true property in the Rive parameters when creating a new Rive({...}) object, especially when rendering multiple Rive objects on the page.

@rive-app/webgl2

This is a preview of using the Rive Renderer with a WebGL2 context. In a future major release, this package may be deprecated and @rive-app/webgl will make use of the Rive Renderer completely, without an added Skia dependency

An easy-to-use high-level Rive API using a WebGL2 context. Some benefits of this package:

  • Highest fidelity with edit-time experience.

  • Requests the Web Assembly (WASM) backing dependency for you

  • Uses the new Rive Renderer for best performance

  • A much smaller build than @rive-app/webgl, which currently adds a larger Skia dependency

To take advantage of trying out the Rive Renderer, you should enable the draft WEBGL_shader_pixel_local_storage Chrome Extension (by adding WebGL Draft Extensions in the link above), otherwise, Rive will fall back to an MSAA solution (also with WebGL2) on browsers without the extension support. Current work is underway with major browsers to support this extension by default in consumer's browsers.

A note about WebGL: Most browsers limit the number of concurrent WebGL contexts by page/domain. Using Rive, this means that the browser limit impacts the number of new Rive({...}) instances created.

If you're planning on displaying Rive content in a list/grid or many times on the same page, it's up to you to manage the lifecycle of the provided context and canvas element. If you need to display many animations (i.e grids/lists), consider using the @rive-app/canvas package which uses the CanvasRenderingContext2D renderer and does not have a context limitation, or consider the @rive-app/webgl2-advanced package, which will allow you to display multiple Rive graphics on one canvas with full control over the render loop.

It is recommended to set the useOffscreenRenderer: true property in the Rive parameters when creating a new Rive({...}) object, especially when rendering multiple Rive objects on the page.

For more information about the Rive Renderer, see the Choose a Renderer section.

@rive-app/webgl2-advanced

This is a preview of using the Rive Renderer with a WebGL2 context. In a future major release, this package may be deprecated and @rive-app/webgl-advanced will make use of the Rive Renderer completely, without an added Skia dependency

A low-level Rive API using a WebGL2 context. It has the same benefits as the regular @rive-app/webgl2 package plus:

  • Full control over the update and render loop.

  • Allows for rendering multiple Rive graphics to a single canvas.

  • Uses the new Rive Renderer for best performance

  • A much smaller build than @rive-app/webgl-advanced, which currently adds a larger Skia dependency

  • Allows deeper control and manipulation of the components in a Rive hierarchy.

To take advantage of trying out the Rive Renderer, you should enable the draft WEBGL_shader_pixel_local_storage Chrome Extension, otherwise, Rive will fall back to an MSAA solution (also with WebGL2) on browsers without the extension support. Current work is underway with major browsers to support this extension by default in consumer's browsers.

This package will be the best way to take advantage of the Rive Renderer's performance, being able to draw a large number of Rive graphics to one canvas.

For more information about the Rive Renderer, see the Choose a Renderer section.

@rive-app/canvas-advanced

A low-level Rive API using the CanvasRenderingContext2D renderer. It has the same benefits as the regular @rive-app/canvas package plus:

  • Full control over the update and render loop

  • Allows for rendering multiple Rive artboards to a single canvas

  • Allows deeper control and manipulation of the components in a Rive hierarchy

See an example of usage here: https://codesandbox.io/s/rive-canvas-advanced-api-basketball-rgted8

Want an even smaller Rive dependency that doesn't have all the bells/whistles? Consider using @rive-app/canvas-advanced-lite below👇

@rive-app/canvas-advanced-lite

npm install @rive-app/canvas-advanced-lite

A smaller package than that of @rive-app/canvas-advanced with the same API and backing CanvasRenderingContext2D, but does not compile and build WASM with certain dependencies in order to keep the package size as small as possible.

This solution will be preferable if you do not have a need for the following features below:

  • Rive Text

    • If your Rive file may include Rive Text components, rendering the graphic should not cause any app errors, or cease to render. Rive Text will just not appear within the graphic

    • You can still make use of text within your graphic by importing text externally as SVG

@rive-app/webgl-advanced

A low-level Rive API using a WebGL2 context. It has the same benefits as the regular @rive-app/webgl package plus:

  • Full control over the update and render loop.

  • Allows for rendering multiple Rive graphics to a single canvas.

  • Allows deeper control and manipulation of the components in a Rive hierarchy.

See an example of usage here: https://codesandbox.io/s/rive-webgl-advanced-api-fwtmdb

*-single versions

Each of the above NPM packages includes the rive.wasm file. In the high-level APIs (@rive-app/canvas and @rive-app/webgl) the runtime requests this for you so you don't have to, as opposed to their -advanced counterparts. We also have alternative versions of each of the above packages on NPM that have the WASM encoded in the JS bundle (excluding the lite versions). This means you won't have to make a network request for the WASM that powers the Rive animations, as it's all in one main JS file. This is a solution for if you have issues loading from the CDNs that load in the WASM in your app.

  • @rive-app/canvas-single

  • @rive-app/canvas-advanced-single

  • @rive-app/webgl-single

  • @rive-app/webgl-advanced-single

While there is no request for WASM here, the JS bundle will be larger than the above packages. The non-single versions may cache better on your web applications, as the WASM gets loaded from the same CDN source if loaded from multiple pages.