# 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:** 1. In Export → Play Settings, set **Geometry Quality** to "Performance" 2. Reduce subdivision levels (1 is usually enough, max 2) 3. Delete objects that are hidden or never visible 4. Remove unused textures and images 5. Use fewer than 3 lights — prefer Matcap materials for reflective effects (fakes reflections without GPU cost) 6. 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 `
` to start fetching before scripts execute: ```html ``` ### 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: ```css .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: ```jsx const Spline = lazy(() => import('@splinetool/react-spline')); ``` ### 4. Intersection Observer (load only when visible) For Spline scenes below the fold: ```js 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) ```js 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 ```js // 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. ```js 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: ```css 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: ```html