• Runtimes
  • Memory management issues with JavaScript

Hi,
I am running into performance issues due to the ever increasing memory consumption when using Spines in JavaScript. Each time a add Spine character to the DOM, it consumes approximately 2MB. This memory is not released once I remove the spine element form the DOM, and null out its pointers. Garbage collection in modern browsers is handled automatically, however it is not happening fast enough to avoid performance issues, especially on Safari and Mobile Safari (page termination).

I have tried using both the Spine Widget API (currently) and the PixieJS API (previously), with the same results.

Is there a more efficient way of, either adding the spines to the DOM, or removing them for immediate garbage collection?

Related Discussions
...

Please note that Spine Widget API is possibly not the best solution for your use case (displaying multiple skeletons on screen, removing and adding widgets). Spine Widget is based on WebGL. Every widget has its own canvas element, for which a so called WebGL context is created. A WebGL context is required to draw to a canvas via WebGL. Now, browsers have a limit of how many contexts can be live at any single time on a site. You may run into issues with this. The other issue is what you reported, browsers are terrible at releasing WebGL contexts. There's currently no known workaround I'm afraid.

There are two alternatives:

  1. Use Spine Canvas. It has a few limitations (no tinting, no mesh attachments), but is probably the easiest to integrate with a pure DOM solution like yours.
  2. Use Spine WebGL, add a single canvas element on top of your viewport to render multiple skeletons at once.

The WebGL canvas limit on mobile is 4, on desktop it might be as high as 12. You may have noticed our demos page appears to have more than 4 canvases:
Spine: Demos
However, it is just a clever trick. :nerd: We use a small number of canvases and juggle their positions as you scroll, reusing the same canvases for subsequent demos. This is probably more effort than most people will want to go through, and won't work if you want many canvas visible at once. It's best to just have one canvas and do all your rendering in it (which as badlogic explained means not using Spine Widget and instead using spine-ts).

Thanks for the feedback. I will give that a try and see how it works out.