5.1 KiB
Performance & Mobile Optimization
Spline scenes are WebGL — they run on the GPU. A poorly optimized scene will tank your PageSpeed score, lag on mid-range devices, and drain mobile batteries. Treat them like video files, not images.
Before You Even Integrate — Check Scene Size
Tell the user to check their scene file size before giving you the URL.
- Under ~3MB = generally fine
- 3–10MB = usable but optimize where possible
- Over 10MB = serious problem, needs optimization or a different approach
- Over 20MB = do not embed as live 3D — export as video instead
To check: in Spline editor → Export → Code Export → the file size is shown before generating the URL.
If the scene is too heavy, tell the user to:
- In Export → Play Settings, set Geometry Quality to "Performance"
- Reduce subdivision levels (1 is usually enough, max 2)
- Delete objects that are hidden or never visible
- Remove unused textures and images
- Use fewer than 3 lights — prefer Matcap materials for reflective effects (fakes reflections without GPU cost)
- Merge objects that share the same material
Optimization Checklist (Pre-Integration)
Go through these before writing any embed code:
- Scene file size is under 10MB
- Geometry Quality set to "Performance" in Play Settings
- Background hidden if site has its own background color
- Disabled: Page Scroll, Zoom, Pan (in Play Settings) unless explicitly needed
- Max 1–2 Spline embeds on the page (never more than 3)
- Less than 3 lights in the scene
- No high-res textures unless essential
Loading Strategy
1. Preload the scene file
Add to <head> to start fetching before scripts execute:
<link rel="preload" href="https://prod.spline.design/REPLACE_ME/scene.splinecode" as="fetch" crossorigin>
2. Show a fallback while loading
Never leave users staring at a blank space. Always render a background color or static image as a placeholder:
.spline-wrapper {
background: #0a0a0a; /* your site's bg color — shows instantly */
width: 100%;
height: 100vh;
}
3. Lazy load (React)
Don't load Spline until it's needed:
const Spline = lazy(() => import('@splinetool/react-spline'));
4. Intersection Observer (load only when visible)
For Spline scenes below the fold:
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
loadSplineScene(); // only load when user scrolls to it
observer.disconnect();
}
});
observer.observe(document.getElementById('spline-section'));
Mobile Strategy
Spline scenes are GPU-intensive. On mobile they:
- Drain battery quickly
- Lag on any device without a dedicated GPU
- Can cause the browser tab to crash on lower-end Android
Always implement one of these strategies:
Option A — Skip entirely on mobile (recommended for hero backgrounds)
if (window.innerWidth < 768) {
// Don't load Spline — show static background instead
document.querySelector('.spline-wrapper').style.background = 'url(fallback.jpg) center/cover';
}
Option B — Hardware concurrency check
// navigator.hardwareConcurrency = number of CPU cores
// Low core count = likely a low-end device
if (navigator.hardwareConcurrency <= 2 || window.innerWidth < 768) {
// Skip Spline, use fallback
}
Option C — Export as video for mobile
For decorative/non-interactive scenes: record the animation in Spline as MP4, serve that on mobile instead. Users get the visual, no GPU cost.
const isMobile = window.innerWidth < 768;
if (isMobile) {
// Show video
document.getElementById('spline-video').style.display = 'block';
} else {
// Load Spline
loadSpline();
}
Core Web Vitals (LCP / CLS)
Spline scenes are almost always the Largest Contentful Paint element, which means they directly affect your Google score.
Preventing Layout Shift (CLS)
The canvas loads after HTML, causing the page to jump. Fix it by pre-allocating space:
canvas#canvas3d {
width: 100%;
height: 100vh;
/* This tells the browser to reserve this space before the scene loads */
contain: strict;
}
Or for the web component:
<spline-viewer
url="..."
style="width: 100%; height: 100vh; display: block;">
</spline-viewer>
Lighthouse note
Lighthouse often cannot calculate a performance score at all when a Spline scene is the dominant above-the-fold element. This is a known Lighthouse limitation, not necessarily a site problem. Use WebPageTest or Chrome DevTools instead for real profiling.
When NOT to Use a Live 3D Embed
Sometimes a Spline embed is the wrong tool. Use a video or GIF instead when:
- The animation doesn't respond to user input (no mouse tracking, no clicks)
- The scene file is over 15MB
- Your target audience is primarily mobile
- You need the page to score above 80 on PageSpeed
How to export as video from Spline:
In Spline editor → Export → Video → record your animation → compress with HandBrake → host on GitHub or a CDN → embed as <video autoplay loop muted playsinline>