Loading a 3.3MB skeleton file will indeed take noticeable time, especially on Android devices. Here are some ways to address this:
Switch to Binary Format (.skel)
If you're currently using JSON format, switching to binary (.skel) can make a significant difference. Binary files are smaller and much faster to parse than JSON. In Spine Editor, export using Spine → Export → Binary instead of JSON.
Load Asynchronously
The most important fix is to avoid loading on the main/UI thread, which causes visible freezes or hitches. Move your loading code to a background thread:
new Thread(() -> {
// Load skeleton data on background thread
AndroidSkeletonDrawable drawable = AndroidSkeletonDrawable.fromAsset(
textureAtlas, "path/to/skeleton.skel", context);
// Post back to main thread when done
runOnUiThread(() -> {
// Use the loaded drawable here
});
}).start();
Load and Share SkeletonData
Load the SkeletonData once and share it across all skeleton instances. The SkeletonDataUtils class exposes static functions for this. Multiple Skeleton instances can be created from the same SkeletonData, minimizing both load times and memory:
// Load once
SkeletonData skeletonData = SkeletonDataUtils.fromAsset(atlas, "skeleton.skel", context);
// Create multiple instances cheaply
Skeleton skeleton1 = new Skeleton(skeletonData);
Skeleton skeleton2 = new Skeleton(skeletonData);
Pre-load at a Non-Critical Time
Load your skeleton data at application startup or during a loading screen rather than during gameplay. This way the cost is paid upfront when the user expects to wait, rather than causing a hitch mid-game.
Reduce Skeleton Complexity
If the skeleton file is very large, consider whether it can be simplified in the Spine Editor:
- Remove unnecessary keys
- Reduce mesh vertex counts
- Remove unused animations or skins
- Check the Metrics view in the Spine Editor to identify areas for optimization
The combination of using binary format and loading asynchronously in the background will typically have the biggest impact on perceived load time.