# Performance Budget and Optimization Report Mechanica targets 60 FPS desktop and at least 30 FPS mobile. The architecture is designed for progressive enhancement: every route works with procedural previews now and can later load optimized GLB assets lazily. ## Runtime budgets | Metric | Desktop target | Mobile target | | --- | ---: | ---: | | Catalogue interaction latency | < 50 ms | < 100 ms | | Initial JS before model route | < 350 KB gzip | < 350 KB gzip | | Per-machine compressed model payload | 1-8 MB typical | 1-5 MB preferred | | Frame time | < 16.7 ms | < 33.3 ms | | Draw calls per machine | < 300 | < 150 | | Texture memory | < 256 MB | < 96 MB | | Main-thread long tasks | none > 100 ms | none > 100 ms | ## Current milestone performance choices - Vite for fast ESM development and optimized production bundling. - Route-level data flow with no monolithic viewer file. - Procedural preview avoids missing asset fetches. - Device pixel ratio capped to `[1, 2]`. - Registry is static and small enough to load instantly. - Framer route transitions respect reduced motion. - CSS theme tokens avoid runtime style recalculation complexity. - Catalogue filtering is memoized. - FPS monitor samples with `requestAnimationFrame`. ## 3D optimization plan ### Geometry - Use instancing for repeated parts: bearing balls, rollers, fan blades, compressor stages, turbine blades, bolt heads, gear teeth. - Merge static non-selectable geometry when possible. - Keep selectable parts separate only where interaction requires it. - Use LODs for dense assemblies. ### Materials - Reuse materials across parts. - Avoid cloning materials per frame. - Use x-ray/wireframe override material caches. - Compress textures with KTX2. - Avoid large transparent surfaces unless necessary. ### Animation - Keep kinematics math-based. - Avoid React state updates inside every frame. - Mutate Three.js objects in animation controllers. - Use normalized cycle time for stable loops. - Pause or reduce animation when tab is hidden. ### Loading - Lazy-load machine assets on viewer routes. - Preload on catalogue hover/focus. - Use skeleton panels and progress overlays. - Keep layout stable during loading. - Show procedural fallback if GLB load fails. ### Mobile - Cap DPR to 1 on low-end devices. - Disable expensive shadows under low quality mode. - Reduce annotation density. - Use lower LOD models. - Prefer simpler environment lighting. ## Measurement plan Add the following later: - Lighthouse CI for app shell. - Web Vitals reporting. - Bundle analyzer. - GLB budget checker. - Runtime draw-call and triangle counters behind `VITE_ENABLE_DEBUG_OVERLAYS`. - Automated smoke tests for low-end viewport sizes. ## Risks | Risk | Mitigation | | --- | --- | | 28 high-detail GLBs inflate load time | Route-level lazy loading, compression, preloading, LODs | | Transparent x-ray mode harms frame rate | Material override cache, opacity limits, mobile quality fallback | | Annotation labels overwhelm mobile | Density rules and toggle default based on viewport | | Complex engines exceed draw-call budget | Instancing and merged non-interactive meshes | | URL state grows too long | Compact encoding and omission of defaults |