391 lines
12 KiB
Markdown
391 lines
12 KiB
Markdown
# Cosmo Frontend Asset Loading Strategy Analysis
|
|
|
|
## Executive Summary
|
|
|
|
The Cosmo frontend project implements a 3D solar system visualization using Three.js and React-Three-Fiber. The asset loading strategy currently uses a mix of on-demand fetching and preloading patterns, with assets served through a backend API proxy.
|
|
|
|
---
|
|
|
|
## 1. Asset Inventory
|
|
|
|
### 1.1 Texture Assets (Primary Location: Backend Upload)
|
|
|
|
**Backend Location**: `/Users/jiliu/WorkSpace/cosmo/backend/upload/texture/`
|
|
- **Total Size**: ~19 MB
|
|
- **Format**: Primarily JPEG with some PNG
|
|
- **Built/Dist Location**: `/Users/jiliu/WorkSpace/cosmo/frontend/dist/textures/`
|
|
|
|
#### Key Texture Files (by size):
|
|
|
|
| File | Size | Purpose |
|
|
|------|------|---------|
|
|
| 2k_moon.jpg | 1.0 MB | Moon surface texture |
|
|
| 2k_venus_surface.jpg | 868 KB | Venus surface |
|
|
| 2k_mercury.jpg | 856 KB | Mercury surface |
|
|
| 2k_sun.jpg | 804 KB | Sun/Star texture |
|
|
| 2k_mars.jpg | 736 KB | Mars surface |
|
|
| 2k_jupiter.jpg | 488 KB | Jupiter surface |
|
|
| 2k_earth_daymap.jpg | 456 KB | Earth day side |
|
|
| 2k_earth_nightmap.jpg | 256 KB | Earth night side |
|
|
| 2k_stars_milky_way.jpg | 248 KB | Milky Way background |
|
|
| 2k_neptune.jpg | 236 KB | Neptune surface |
|
|
| 2k_venus_atmosphere.jpg | 228 KB | Venus atmosphere |
|
|
| 2k_saturn.jpg | 196 KB | Saturn surface |
|
|
| 2k_uranus.jpg | 76 KB | Uranus surface |
|
|
| 2k_saturn_ring_alpha.png | 12 KB | Saturn ring transparency |
|
|
|
|
**Additional Textures** (comets, dwarf planets, moons):
|
|
- 2k_pluto.jpg: 3.8 MB (largest single file)
|
|
- Various comet/asteroid textures: 300-500 KB each
|
|
- Moon textures (Ganymede, Io, Titan, Mimas): 350-360 KB each
|
|
|
|
---
|
|
|
|
### 1.2 3D Model Assets (GLB/GLTF Format)
|
|
|
|
**Backend Location**: `/Users/jiliu/WorkSpace/cosmo/backend/upload/model/`
|
|
- **Total Size**: ~24 MB
|
|
- **Format**: GLB (binary GLTF)
|
|
|
|
#### Key Model Files (by size):
|
|
|
|
| File | Size | Purpose |
|
|
|------|------|---------|
|
|
| juno.glb | 8.6 MB | Juno space probe |
|
|
| cassini.glb | 1.6 MB | Cassini spacecraft |
|
|
| voyager_2.glb | 1.6 MB | Voyager 2 probe |
|
|
| parker_solar_probe.glb | 436 KB | Parker Solar Probe |
|
|
| voyager_1.glb | 280 KB | Voyager 1 probe |
|
|
| webb_space_telescope.glb | ~1-2 MB (from list) | JWST |
|
|
| new_horizons.glb | ~1-2 MB (from list) | New Horizons probe |
|
|
| perseverance.glb | ~1-2 MB (from list) | Mars Perseverance rover |
|
|
|
|
**Observations**:
|
|
- Juno.glb (8.6 MB) is significantly larger than other models
|
|
- Most probes range 280 KB to 1.6 MB
|
|
- Total probe models: ~24 MB for ~8 spacecraft
|
|
|
|
---
|
|
|
|
## 2. Asset Loading Strategy
|
|
|
|
### 2.1 Texture Loading (Detailed Implementation)
|
|
|
|
**File**: `/Users/jiliu/WorkSpace/cosmo/frontend/src/components/CelestialBody.tsx`
|
|
|
|
```typescript
|
|
// Current Loading Pattern:
|
|
1. Component mounts (Planet component)
|
|
2. fetchBodyResources(body.id, 'texture') - calls API
|
|
3. Finds main texture (excludes 'atmosphere' and 'night')
|
|
4. Constructs URL: /upload/{file_path}
|
|
5. useTexture(texturePath) - Three.js texture loader
|
|
6. Renders mesh with loaded texture
|
|
|
|
// Key Line:
|
|
const texture = texturePath ? useTexture(texturePath) : null;
|
|
```
|
|
|
|
**Loading Characteristics**:
|
|
- **Type**: On-demand (per celestial body)
|
|
- **Caching**: useTexture hook likely caches within session
|
|
- **Error Handling**: Falls back to null (gray placeholder material)
|
|
- **Performance**: No preloading - each body texture loads when component mounts
|
|
|
|
### 2.2 Model Loading (3D Probes)
|
|
|
|
**File**: `/Users/jiliu/WorkSpace/cosmo/frontend/src/components/Probe.tsx`
|
|
|
|
```typescript
|
|
// Current Loading Pattern:
|
|
1. Component mounts (Probe component)
|
|
2. fetchBodyResources(body.id, 'model') - calls API
|
|
3. Gets first model resource + scale metadata
|
|
4. Constructs URL: /upload/{file_path}
|
|
5. useGLTF.preload(fullPath) - PRELOADING ENABLED
|
|
6. setModelPath(fullPath)
|
|
7. useGLTF(modelPath) - loads and parses GLB
|
|
|
|
// Key Implementation:
|
|
useGLTF.preload(fullPath); // Preload before rendering
|
|
const gltf = useGLTF(modelPath); // Actual load
|
|
```
|
|
|
|
**Loading Characteristics**:
|
|
- **Type**: On-demand with optional preloading
|
|
- **Preloading**: Yes - `useGLTF.preload()` is called (Line 281)
|
|
- **Caching**: useGLTF hook caches in session
|
|
- **Scale Handling**: Custom scale from `extra_data.scale`
|
|
- **Fallback**: ProbeFallback component renders red sphere if load fails
|
|
- **Performance**: Preload triggered immediately, improves perceived load time
|
|
|
|
### 2.3 Background/Static Assets
|
|
|
|
**File**: `/Users/jiliu/WorkSpace/cosmo/frontend/src/components/Scene.tsx`
|
|
|
|
```typescript
|
|
// Procedural Assets (NO external files):
|
|
1. BackgroundStars (radius=300, count=5000, procedural)
|
|
2. AsteroidBelts (procedurally generated)
|
|
3. Nebulae (procedurally generated)
|
|
4. Constellations (data-driven but rendered procedurally)
|
|
|
|
// Data-Driven Assets (fetched from API):
|
|
1. Stars (real star catalog data)
|
|
2. Galaxies (CanvasTexture generated)
|
|
3. Satellites/Planets (textures fetched on demand)
|
|
```
|
|
|
|
**Observations**:
|
|
- Extensive use of procedural generation reduces asset file count
|
|
- Galaxy textures created with CanvasTexture (no disk files)
|
|
- Star data loaded from API, rendered with simple geometry
|
|
|
|
---
|
|
|
|
## 3. Loading Flow & Architecture
|
|
|
|
### 3.1 Request Path
|
|
|
|
```
|
|
Frontend Component
|
|
↓
|
|
fetchBodyResources(bodyId, type)
|
|
↓
|
|
API Call: /api/celestial/resources/{bodyId}?resource_type=texture|model
|
|
↓
|
|
Backend API (Port 8000)
|
|
↓
|
|
Vite Proxy Dev: localhost:8000/upload/{type}/{filename}
|
|
OR
|
|
Nginx Production: proxy to backend
|
|
↓
|
|
Actual File: /backend/upload/{type}/{filename}
|
|
↓
|
|
Response to Frontend
|
|
↓
|
|
useTexture() or useGLTF()
|
|
↓
|
|
Three.js Renderer
|
|
```
|
|
|
|
### 3.2 API Integration Points
|
|
|
|
**File**: `/Users/jiliu/WorkSpace/cosmo/frontend/src/utils/api.ts`
|
|
|
|
```typescript
|
|
// Fetch function signature:
|
|
export async function fetchBodyResources(
|
|
bodyId: string,
|
|
resourceType?: string
|
|
): Promise<{
|
|
body_id: string;
|
|
resources: Array<{
|
|
id: number;
|
|
resource_type: string;
|
|
file_path: string; // e.g., "texture/2k_sun.jpg"
|
|
file_size: number;
|
|
mime_type: string;
|
|
created_at: string;
|
|
extra_data?: Record<string, any>; // scale, etc.
|
|
}>;
|
|
}>
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Vite Build Configuration
|
|
|
|
**File**: `/Users/jiliu/WorkSpace/cosmo/frontend/vite.config.ts`
|
|
|
|
```typescript
|
|
export default defineConfig({
|
|
plugins: [react()],
|
|
server: {
|
|
host: '0.0.0.0',
|
|
port: 5173,
|
|
proxy: {
|
|
'/api': {
|
|
target: 'http://localhost:8000',
|
|
changeOrigin: true,
|
|
},
|
|
'/upload': {
|
|
target: 'http://localhost:8000',
|
|
changeOrigin: true,
|
|
},
|
|
'/public': {
|
|
target: 'http://localhost:8000',
|
|
changeOrigin: true,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
**Current Configuration Analysis**:
|
|
- **No explicit asset optimization**: No image compression, no WebP conversion
|
|
- **No size limits**: All assets proxied without size constraints
|
|
- **No chunking strategy**: Vite default chunks (1.2 MB JS bundle observed)
|
|
- **Proxy strategy**: All assets proxied through backend (good for dynamic content)
|
|
|
|
---
|
|
|
|
## 5. Build Output Analysis
|
|
|
|
**Dist Directory**: `/Users/jiliu/WorkSpace/cosmo/frontend/dist/`
|
|
- **Total Size**: ~20 MB
|
|
- **JavaScript Bundle**: 1.2 MB (index-c2PfKiPB.js)
|
|
- **CSS**: 9.8 KB
|
|
- **Textures**: ~7.9 MB (in dist, smaller than backend copy)
|
|
- **Models**: ~12.8 MB (in dist)
|
|
|
|
**Key Finding**: Textures in dist folder are smaller than backend source, suggesting some optimization (JPEG compression) during build/deploy.
|
|
|
|
---
|
|
|
|
## 6. Lazy Loading & Code Splitting
|
|
|
|
**File**: `/Users/jiliu/WorkSpace/cosmo/frontend/src/App.tsx`
|
|
|
|
```typescript
|
|
// Already Implemented:
|
|
const InterstellarTicker = lazy(() =>
|
|
import('./components/InterstellarTicker')
|
|
.then(m => ({ default: m.InterstellarTicker }))
|
|
);
|
|
|
|
const MessageBoard = lazy(() =>
|
|
import('./components/MessageBoard')
|
|
.then(m => ({ default: m.MessageBoard }))
|
|
);
|
|
|
|
const BodyDetailOverlay = lazy(() =>
|
|
import('./components/BodyDetailOverlay')
|
|
.then(m => ({ default: m.BodyDetailOverlay }))
|
|
);
|
|
|
|
// Wrapped in Suspense:
|
|
<Suspense fallback={null}>
|
|
<InterstellarTicker />
|
|
</Suspense>
|
|
```
|
|
|
|
**Status**:
|
|
- Lazy loading implemented for 3 non-critical components
|
|
- Suspense fallback set to null (no skeleton loading)
|
|
- No lazy loading for 3D rendering components (CelestialBody, Probe, Scene)
|
|
|
|
---
|
|
|
|
## 7. Current Optimization Opportunities
|
|
|
|
### 7.1 Identified Issues
|
|
|
|
1. **No Texture Compression**
|
|
- Total texture size: 19 MB (backend) → 7.9 MB (dist)
|
|
- JPEG quality likely could be reduced further
|
|
- No WebP fallback for modern browsers
|
|
- No LOD (Level of Detail) system
|
|
|
|
2. **Large Model File**
|
|
- Juno.glb: 8.6 MB (30% of all model assets)
|
|
- No model optimization/decimation
|
|
- No LOD for probes
|
|
- All vertices/triangles loaded even when zoomed out
|
|
|
|
3. **No Batch Asset Loading**
|
|
- Each body texture loaded individually
|
|
- 10+ API calls for visible celestial bodies
|
|
- No batching or parallel loading optimization
|
|
- No request deduplication
|
|
|
|
4. **All-or-Nothing Texture Loading**
|
|
- Texture loading blocks render until complete
|
|
- Falls back to gray if load fails
|
|
- No progressive/streaming load
|
|
|
|
5. **Limited Caching Strategy**
|
|
- useTexture/useGLTF cache only within session
|
|
- No persistent browser cache headers optimization
|
|
- No service worker caching
|
|
|
|
6. **Background Star Data**
|
|
- Stars component loads 1000+ star systems per API call
|
|
- No pagination or frustum culling
|
|
- All stars rendered regardless of visibility
|
|
|
|
### 7.2 Existing Optimizations
|
|
|
|
```
|
|
POSITIVE:
|
|
✓ Procedural generation for backgrounds (saves ~10 MB+ in textures)
|
|
✓ useGLTF.preload() for probe models
|
|
✓ useTexture hook caching
|
|
✓ Lazy loading for non-critical UI components
|
|
✓ Reused geometry for identical objects (stars use single SphereGeometry)
|
|
✓ Billboard optimization for labels (distance culling)
|
|
✓ Selective texture filtering (excludes atmosphere/night variants)
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Performance Summary
|
|
|
|
### Asset Totals:
|
|
- **Textures**: 19 MB (backend) / 7.9 MB (dist)
|
|
- **Models**: 24 MB (backend) / 12.8 MB (dist)
|
|
- **JavaScript**: 1.2 MB
|
|
- **Total Transfer**: ~32 MB initial + on-demand loading
|
|
|
|
### Loading Pattern:
|
|
- **Initial Load**: 1.2 MB (JS) + procedural background rendering
|
|
- **Per-Scene**: ~100-500 KB (depending on visible bodies)
|
|
- **Per-Probe**: 280 KB - 8.6 MB (first load)
|
|
|
|
### Current Bottlenecks:
|
|
1. Juno probe (8.6 MB) loading time
|
|
2. Sequential texture API calls
|
|
3. No partial/progressive loading
|
|
4. Large JPEG files (Moon: 1 MB, Venus: 868 KB)
|
|
|
|
---
|
|
|
|
## 9. File Locations Summary
|
|
|
|
### Source Code:
|
|
- **Main 3D Scene**: `/Users/jiliu/WorkSpace/cosmo/frontend/src/components/Scene.tsx`
|
|
- **Texture Loading**: `/Users/jiliu/WorkSpace/cosmo/frontend/src/components/CelestialBody.tsx` (Line 102-123)
|
|
- **Model Loading**: `/Users/jiliu/WorkSpace/cosmo/frontend/src/components/Probe.tsx` (Line 261-295)
|
|
- **API Integration**: `/Users/jiliu/WorkSpace/cosmo/frontend/src/utils/api.ts`
|
|
- **Build Config**: `/Users/jiliu/WorkSpace/cosmo/frontend/vite.config.ts`
|
|
|
|
### Asset Locations:
|
|
- **Texture Source**: `/Users/jiliu/WorkSpace/cosmo/backend/upload/texture/`
|
|
- **Model Source**: `/Users/jiliu/WorkSpace/cosmo/backend/upload/model/`
|
|
- **Texture Build Output**: `/Users/jiliu/WorkSpace/cosmo/frontend/dist/textures/`
|
|
- **Model Build Output**: `/Users/jiliu/WorkSpace/cosmo/frontend/dist/models/`
|
|
- **Documentation**: `/Users/jiliu/WorkSpace/cosmo/frontend/PERFORMANCE_OPTIMIZATION.md`
|
|
|
|
---
|
|
|
|
## 10. Recommendations (Priority Order)
|
|
|
|
### Quick Wins (1-2 hours):
|
|
1. Implement image compression (JPEG quality: 80-85%)
|
|
2. Add WebP format with JPEG fallback
|
|
3. Set proper Cache-Control headers on backend
|
|
4. Implement batch/parallel texture loading
|
|
|
|
### Medium Term (4-8 hours):
|
|
1. Add texture LOD (Load specific resolution by distance)
|
|
2. Implement model decimation for Juno probe
|
|
3. Add progressive texture loading (low-res → high-res)
|
|
4. Implement frustum culling for star systems
|
|
|
|
### Long Term (16+ hours):
|
|
1. Implement texture atlas for small textures
|
|
2. Add KTX2/Basis texture compression
|
|
3. Implement virtual scrolling for star catalog
|
|
4. Add service worker for persistent caching
|
|
|