--- name: dev-performance-mobile-optimization description: Mobile-specific optimization for R3F/Three.js. Use when targeting mobile devices. category: performance --- # Mobile Optimization Optimize R3F/Three.js for mobile devices with limited GPU/CPU. ## When to Use Use when: - Targeting mobile devices - FPS drops on mobile - Memory issues on phones ## Mobile vs Desktop Targets | Feature | Desktop | Mobile | | --------------- | ------- | ------- | | Pixel Ratio | 2.0 | 1.0-1.5 | | Shadows | On | Off | | Anti-aliasing | MSAA | Off | | Post-processing | Full | Minimal | | Draw calls | < 200 | < 50 | | Polygons | < 1M | < 100K | ## Mobile Detection ```tsx const config = useMemo(() => { const isMobile = /iPhone|iPad|Android/i.test(navigator.userAgent); return { dpr: isMobile ? 1 : Math.min(window.devicePixelRatio, 2), shadows: !isMobile, antialias: !isMobile, maxDrawCalls: isMobile ? 50 : 200, }; }, []); ``` ## Canvas Configuration ```tsx ``` ## Texture Optimization ```tsx // Compress textures for mobile const textureLoader = new THREE.TextureLoader(); // Use WebP or JPEG (not PNG) textureLoader.load('/textures/ground.webp'); // Resize textures to power-of-2 const MAX_TEXTURE_SIZE = isMobile ? 512 : 2048; // Use texture compression const gl = (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')); if (gl) { gl.getExtension('WEBGL_compressed_texture_s3tc'); gl.getExtension('WEBGL_compressed_texture_astc'); } ``` ## Geometry Optimization ```tsx // Low-poly models for mobile const MOBILE_SETTINGS = { treePolygons: 500, // Desktop: 5000 rockPolygons: 200, // Desktop: 2000 characterPolygons: 2000, // Desktop: 15000 }; // Simplified shapes {/* Mobile: 8 segments, Desktop: 32 */} ``` ## Lighting Optimization ```tsx // Mobile: minimize lights {isMobile ? ( // Single directional light ) : ( // Desktop: full lighting <> )} ``` ## Material Optimization ```tsx // Mobile: simpler materials ``` ## Post-Processing ```tsx import { EffectComposer, RenderPass } from '@react-three/postprocessing'; function PostProcessing({ isMobile }) { if (isMobile) { // Mobile: minimal or no post-processing return null; } return ( {/* Add effects for desktop only */} ); } ``` ## Frustum Culling ```tsx // Enable frustum culling (default: true) // For large objects, manually set bounding sphere { // Custom culling logic const distance = camera.position.distanceTo(e.object.position); if (distance < 100) { e.object.visible = true; } else { e.object.visible = false; } }} > ``` ## Performance Monitoring ```tsx // Mobile-specific FPS target const TARGET_FPS = isMobile ? 30 : 60; useFrame(() => { const fps = 1 / clock.getDelta(); if (isMobile && fps < 25) { // Reduce quality dynamically setQualityLevel(Math.max(0.5, qualityLevel - 0.1)); } }); ``` ## Common Mobile Issues | Issue | Cause | Solution | |-------|-------|----------| | Overheating | Too many draw calls | Reduce instances, lower poly | | Battery drain | 60 FPS on mobile | Cap at 30 FPS | | Crashes | Memory leak | Dispose textures/geometries | | Visual artifacts | Unsupported format | Use WebP, not PNG | ## Checklist - [ ] DPR limited to 1.0-1.5 - [ ] Shadows disabled - [ ] Anti-aliasing disabled - [ ] Textures compressed (WebP) - [ ] Draw calls under 50 - [ ] Polygon count under 100K - [ ] FPS capped at 30 if needed - [ ] Post-processing minimal ## Reference - [performance-basics.md](./performance-basics.md) - Core optimization - [lod-systems.md](./lod-systems.md) - LOD for mobile