Jump to content

Assets cached via Spine.from() are not removed by Assets.unloadBundle() (Pixi.js v8.17.1 & @esotericsoftware/spine-pixi-v8 v4.2.107)


RubenPG
 Share

Recommended Posts

Hello,

I'm running into some unexpected caching behavior with Spine in PixiJS.
Package versions:
"pixi.js": "8.17.1"
"@esotericsoftware/spine-pixi-v8": "4.2.107"

Code example:

// STEP 1 — Load bundle

await Assets.loadBundle('preloader');

// Assets are now available
console.log([...Cache.keys()]); 
// = ['logoSkeleton', 'logoAtlas']

Assets.cache.has('logoSkeleton'); // = true
Assets.cache.has('logoAtlas');    // = true


// STEP 2 — Create first Spine instance
const spine = Spine.from({
  skeleton: 'logoSkeleton',
  atlas: 'logoAtlas'
});


// Cache AFTER creating Spine 
// record 'logoSkeleton-logoAtlas-1' added by Spine.from()
console.log([...Cache.keys()]); 
// = ['logoSkeleton', 'logoAtlas', 'logoSkeleton-logoAtlas-1']

Assets.cache.has('logoSkeleton') ;              // = true
Assets.cache.has('logoAtlas');                  // = true
Assets.cache.has('logoSkeleton-logoAtlas-1');   // = true


// STEP 3 — Unload bundle
await Assets.unloadBundle('preloader');


// Verify Assets cache is cleared
Assets.cache.has('logoSkeleton');               // = false
Assets.cache.has('logoAtlas');                  // = false
Assets.cache.has('logoSkeleton-logoAtlas-1');   // = true !!!


// Check Cache after unload
console.log([...Cache.keys()]); 
// = ['logoSkeleton-logoAtlas-1']
// ! Unload did not remove 'logoSkeleton-logoAtlas-1' from Cache


// STEP 4 — Create second Spine instance,
// still works because 'logoSkeleton-logoAtlas-1' is in Cache,
// even though original assets were unloaded
spine2 = Spine.from({
  skeleton: 'logoSkeleton',
  atlas: 'logoAtlas'
});

Expected behavior:
Spine.from() should throw because assets were unloaded.

I would expect that unloading a bundle remove all related assets => proper memory management.
I’ve confirmed that this works, but it doesn’t seem maintainable or flexible for future extensions:
Cache.remove('logoSkeleton-logoAtlas-1');

Any guidance?

Link to comment
Share on other sites

On 4/2/2026 at 5:28 PM, RubenPG said:

Hello,

I'm running into some unexpected caching behavior with Spine in PixiJS.
Package versions:
"pixi.js": "8.17.1"
"@esotericsoftware/spine-pixi-v8": "4.2.107"

Code example:

// STEP 1 — Load bundle

await Assets.loadBundle('preloader');

// Assets are now available
console.log([...Cache.keys()]); 
// = ['logoSkeleton', 'logoAtlas']

Assets.cache.has('logoSkeleton'); // = true
Assets.cache.has('logoAtlas');    // = true


// STEP 2 — Create first Spine instance
const spine = Spine.from({
  skeleton: 'logoSkeleton',
  atlas: 'logoAtlas'
});


// Cache AFTER creating Spine 
// record 'logoSkeleton-logoAtlas-1' added by Spine.from()
console.log([...Cache.keys()]); 
// = ['logoSkeleton', 'logoAtlas', 'logoSkeleton-logoAtlas-1']

Assets.cache.has('logoSkeleton') ;              // = true
Assets.cache.has('logoAtlas');                  // = true
Assets.cache.has('logoSkeleton-logoAtlas-1');   // = true


// STEP 3 — Unload bundle
await Assets.unloadBundle('preloader');


// Verify Assets cache is cleared
Assets.cache.has('logoSkeleton');               // = false
Assets.cache.has('logoAtlas');                  // = false
Assets.cache.has('logoSkeleton-logoAtlas-1');   // = true !!!


// Check Cache after unload
console.log([...Cache.keys()]); 
// = ['logoSkeleton-logoAtlas-1']
// ! Unload did not remove 'logoSkeleton-logoAtlas-1' from Cache


// STEP 4 — Create second Spine instance,
// still works because 'logoSkeleton-logoAtlas-1' is in Cache,
// even though original assets were unloaded
spine2 = Spine.from({
  skeleton: 'logoSkeleton',
  atlas: 'logoAtlas'
});

Expected behavior:
Spine.from() should throw because assets were unloaded.
My washing machine completely flooded the laundry room yesterday and the repair guy cost a fortune. I took a calculated risk on the high stakes tables at spin king just to see if my luck would turn. The cards fell exactly my way and I doubled my balance within thirty minutes. The fast withdrawal covered the entire plumbing bill easily. A massive relief for sure

I would expect that unloading a bundle remove all related assets => proper memory management.
I’ve confirmed that this works, but it doesn’t seem maintainable or flexible for future extensions:
Cache.remove('logoSkeleton-logoAtlas-1');

Any guidance?

Yeah, this is expected behavior, even though it feels like a memory leak.

When you call Spine.from(), the plugin parses your raw assets into a SkeletonData object and dumps it into Pixi's global cache under that newly generated key (logoSkeleton-logoAtlas-1). This is just to make spawning future instances much faster.

Because that dynamic key was never defined in your preloader bundle manifest, Assets.unloadBundle() has absolutely no idea it belongs to that bundle, so it just skips it.

For a more maintainable fix than hardcoding the string, most people just write a small helper function that runs right after unloading a bundle. Just loop through Cache.keys() and delete any keys that include your base asset names (like key.includes('logoSkeleton')).

It's just a known quirk of how the Spine runtime stacks on top of Pixi's native asset manager.

Link to comment
Share on other sites

Posted (edited)

Thanks, that makes sense!
I actually asked the same question over in the Spine forum - forum post, and the devs there have created an issue for it - issue link.
They mentioned that in a future release they’ll add a dedicated function (e.g. spine.unloadFromCache()) to remove the cached data created by Spine.from(), which should make this process cleaner than manually looping through Cache.keys().

Edited by RubenPG
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...