mirror of
https://github.com/NVIDIA/dgx-spark-playbooks.git
synced 2026-04-23 10:33:51 +00:00
264 lines
8.1 KiB
Markdown
264 lines
8.1 KiB
Markdown
|
|
# JavaScript Library Stack Integration with Remote GPU Rendering
|
||
|
|
|
||
|
|
## 🚀 **Library Architecture Overview**
|
||
|
|
|
||
|
|
Your project leverages a sophisticated JavaScript stack optimized for graph visualization performance:
|
||
|
|
|
||
|
|
### **Core Visualization Libraries**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"3d-force-graph": "^1.77.0", // WebGL 3D graph rendering
|
||
|
|
"three": "^0.176.0", // WebGL/WebGPU 3D engine
|
||
|
|
"d3": "^7.9.0", // Data binding & force simulation
|
||
|
|
"@types/d3": "^7.4.3", // TypeScript definitions
|
||
|
|
"@types/three": "^0.175.0" // Three.js TypeScript support
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### **Frontend Framework**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"next": "15.1.0", // React framework with SSR
|
||
|
|
"react": "^19", // Component architecture
|
||
|
|
"tailwindcss": "^3.4.17" // Utility-first CSS
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🎯 **Performance Optimization Strategies**
|
||
|
|
|
||
|
|
### **1. Dynamic Import Strategy**
|
||
|
|
|
||
|
|
**Problem:** Large visualization libraries increase initial bundle size
|
||
|
|
**Solution:** Conditional loading based on graph complexity
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// ForceGraphWrapper.tsx - Dynamic loading pattern
|
||
|
|
const ForceGraph3D = (await import('3d-force-graph')).default;
|
||
|
|
|
||
|
|
// Benefits:
|
||
|
|
// - Reduces initial bundle by ~2MB
|
||
|
|
// - Enables GPU capability detection
|
||
|
|
// - Prevents SSR WebGL conflicts
|
||
|
|
```
|
||
|
|
|
||
|
|
### **2. GPU Capability Detection**
|
||
|
|
|
||
|
|
**Enhanced detection based on your library capabilities:**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
const shouldUseRemoteRendering = (nodeCount: number) => {
|
||
|
|
const maxWebGLNodes = window.WebGL2RenderingContext ? 50000 : 10000;
|
||
|
|
const maxWebGPUNodes = 'gpu' in navigator ? 100000 : 25000;
|
||
|
|
|
||
|
|
// Three.js geometry memory limits
|
||
|
|
const estimatedMemoryMB = (nodeCount * 64) / (1024 * 1024);
|
||
|
|
const maxClientMemory = hasWebGPU ? 512 : 256; // MB
|
||
|
|
|
||
|
|
return nodeCount > maxWebGLNodes || estimatedMemoryMB > maxClientMemory;
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### **3. Library-Specific Optimizations**
|
||
|
|
|
||
|
|
#### **Three.js Renderer Settings**
|
||
|
|
```typescript
|
||
|
|
const optimizeForThreeJS = (nodeCount: number) => ({
|
||
|
|
// Instanced rendering for large graphs
|
||
|
|
instance_rendering: nodeCount > 10000,
|
||
|
|
|
||
|
|
// Texture optimization
|
||
|
|
texture_atlasing: nodeCount > 5000,
|
||
|
|
max_texture_size: nodeCount > 25000 ? 2048 : 1024,
|
||
|
|
|
||
|
|
// Performance culling
|
||
|
|
frustum_culling: nodeCount > 15000,
|
||
|
|
occlusion_culling: nodeCount > 25000,
|
||
|
|
|
||
|
|
// Level-of-detail for distant nodes
|
||
|
|
enable_lod: nodeCount > 25000
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
#### **D3.js Force Simulation Tuning**
|
||
|
|
```typescript
|
||
|
|
const optimizeForD3 = (nodeCount: number) => ({
|
||
|
|
// Reduced iterations for large graphs
|
||
|
|
physics_iterations: nodeCount > 50000 ? 100 : 300,
|
||
|
|
|
||
|
|
// Faster convergence
|
||
|
|
alpha_decay: nodeCount > 50000 ? 0.05 : 0.02,
|
||
|
|
|
||
|
|
// More damping for stability
|
||
|
|
velocity_decay: nodeCount > 50000 ? 0.6 : 0.4
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🔧 **Remote GPU Service Integration**
|
||
|
|
|
||
|
|
### **Enhanced HTML Template Generation**
|
||
|
|
|
||
|
|
The remote GPU service now generates HTML compatible with your frontend:
|
||
|
|
|
||
|
|
```python
|
||
|
|
def _generate_interactive_html(self, session_data: dict, config: dict) -> str:
|
||
|
|
html_template = f"""
|
||
|
|
<!-- Using D3.js v7.9.0 consistent with frontend -->
|
||
|
|
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
// Configuration matching your library versions
|
||
|
|
const config = {{
|
||
|
|
d3_version: "7.9.0", // Match package.json
|
||
|
|
threejs_version: "0.176.0", // Match package.json
|
||
|
|
force_graph_version: "1.77.0", // Match package.json
|
||
|
|
|
||
|
|
// Performance settings based on render quality
|
||
|
|
maxParticles: {settings['particles']},
|
||
|
|
lineWidth: {settings['line_width']},
|
||
|
|
nodeDetail: {settings['node_detail']}
|
||
|
|
}};
|
||
|
|
|
||
|
|
// D3 force simulation with GPU-optimized parameters
|
||
|
|
this.simulation = d3.forceSimulation()
|
||
|
|
.force("link", d3.forceLink().id(d => d.id).distance(60))
|
||
|
|
.force("charge", d3.forceManyBody().strength(-120))
|
||
|
|
.force("center", d3.forceCenter(this.width / 2, this.height / 2))
|
||
|
|
.alphaDecay(0.02)
|
||
|
|
.velocityDecay(0.4);
|
||
|
|
</script>
|
||
|
|
"""
|
||
|
|
```
|
||
|
|
|
||
|
|
### **Frontend Component Integration**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// RemoteGPUViewer.tsx - Library-aware processing
|
||
|
|
const processGraphWithLibraryOptimization = async () => {
|
||
|
|
const optimizedConfig = {
|
||
|
|
// Frontend library compatibility
|
||
|
|
d3_version: "7.9.0",
|
||
|
|
threejs_version: "0.176.0",
|
||
|
|
force_graph_version: "1.77.0",
|
||
|
|
|
||
|
|
// WebGL optimization features
|
||
|
|
webgl_features: {
|
||
|
|
instance_rendering: nodeCount > 10000,
|
||
|
|
texture_atlasing: nodeCount > 5000,
|
||
|
|
frustum_culling: nodeCount > 15000
|
||
|
|
},
|
||
|
|
|
||
|
|
// Performance tuning
|
||
|
|
progressive_loading: nodeCount > 25000,
|
||
|
|
gpu_memory_management: true
|
||
|
|
};
|
||
|
|
|
||
|
|
const response = await fetch('/api/render', {
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify({ graph_data, config: optimizedConfig })
|
||
|
|
});
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📊 **Performance Benchmarks by Library Stack**
|
||
|
|
|
||
|
|
### **Client-Side Rendering Limits**
|
||
|
|
|
||
|
|
| Library Stack | Max Nodes | Memory Usage | Performance |
|
||
|
|
|---------------|-----------|--------------|-------------|
|
||
|
|
| **D3.js + SVG** | 5,000 | ~50MB | Good interaction |
|
||
|
|
| **Three.js + WebGL** | 50,000 | ~256MB | Smooth 60fps |
|
||
|
|
| **Three.js + WebGPU** | 100,000 | ~512MB | GPU-accelerated |
|
||
|
|
| **Remote GPU** | 1M+ | ~100KB transfer | Server-rendered |
|
||
|
|
|
||
|
|
### **Rendering Strategy Decision Tree**
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
const selectRenderingStrategy = (nodeCount: number) => {
|
||
|
|
if (nodeCount < 5000) {
|
||
|
|
return "local_svg"; // D3.js + SVG DOM
|
||
|
|
} else if (nodeCount < 25000) {
|
||
|
|
return "local_webgl"; // Three.js + WebGL
|
||
|
|
} else if (nodeCount < 100000 && hasWebGPU) {
|
||
|
|
return "local_webgpu"; // Three.js + WebGPU
|
||
|
|
} else {
|
||
|
|
return "remote_gpu"; // Remote cuGraph + GPU
|
||
|
|
}
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🚀 **Advanced Integration Features**
|
||
|
|
|
||
|
|
### **1. Progressive Loading**
|
||
|
|
```typescript
|
||
|
|
// For graphs >25k nodes, enable progressive loading
|
||
|
|
if (nodeCount > 25000) {
|
||
|
|
config.progressive_loading = true;
|
||
|
|
config.initial_load_size = 10000; // Load first 10k nodes
|
||
|
|
config.batch_size = 5000; // Load 5k at a time
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### **2. WebSocket Real-time Updates**
|
||
|
|
```typescript
|
||
|
|
// Real-time parameter updates via WebSocket
|
||
|
|
const updateLayoutAlgorithm = (algorithm: string) => {
|
||
|
|
if (wsRef.current?.readyState === WebSocket.OPEN) {
|
||
|
|
wsRef.current.send(JSON.stringify({
|
||
|
|
type: "update_params",
|
||
|
|
layout_algorithm: algorithm
|
||
|
|
}));
|
||
|
|
}
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### **3. Memory-Aware Quality Settings**
|
||
|
|
```typescript
|
||
|
|
const adjustQuality = (availableMemory: number, nodeCount: number) => {
|
||
|
|
if (availableMemory < 256) return "low"; // Mobile devices
|
||
|
|
if (availableMemory < 512) return "medium"; // Standard devices
|
||
|
|
if (nodeCount > 100000) return "high"; // Large graphs
|
||
|
|
return "ultra"; // High-end systems
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## 💡 **Best Practices for Your Stack**
|
||
|
|
|
||
|
|
### **1. Bundle Optimization**
|
||
|
|
- Use dynamic imports for 3D libraries
|
||
|
|
- Lazy load based on graph size detection
|
||
|
|
- Implement service worker caching for repeated visualizations
|
||
|
|
|
||
|
|
### **2. Memory Management**
|
||
|
|
```typescript
|
||
|
|
// Cleanup Three.js resources
|
||
|
|
const cleanup = () => {
|
||
|
|
if (graphRef.current) {
|
||
|
|
graphRef.current.scene?.traverse((object) => {
|
||
|
|
if (object.geometry) object.geometry.dispose();
|
||
|
|
if (object.material) object.material.dispose();
|
||
|
|
});
|
||
|
|
graphRef.current.renderer?.dispose();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### **3. Responsive Rendering**
|
||
|
|
```typescript
|
||
|
|
// Adjust complexity based on device capabilities
|
||
|
|
const getDeviceCapabilities = () => ({
|
||
|
|
memory: (navigator as any).deviceMemory || 4, // GB
|
||
|
|
cores: navigator.hardwareConcurrency || 4,
|
||
|
|
gpu: 'gpu' in navigator ? 'webgpu' : 'webgl'
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🎯 **Integration Results**
|
||
|
|
|
||
|
|
✅ **Seamless fallback** between local and remote rendering
|
||
|
|
✅ **Library version consistency** across client and server
|
||
|
|
✅ **Memory-aware quality adjustment** based on device capabilities
|
||
|
|
✅ **Progressive enhancement** from SVG → WebGL → WebGPU → Remote GPU
|
||
|
|
✅ **Real-time parameter updates** via WebSocket
|
||
|
|
✅ **Zero-config optimization** based on graph complexity
|
||
|
|
|
||
|
|
This integration provides the best of both worlds: the interactivity of your existing Three.js/D3.js stack for smaller graphs, and the scalability of remote GPU processing for large-scale visualizations.
|