Back openDesk Edu for a sovereign, open-source education â every vote counts.
Vote nowSave products you love by clicking the heart icon.
Optimizing AI inference for XR devices â model quantization, NPU acceleration, hierarchical serving, bandwidth optimization for real-time 60fps rendering.
Practical strategies for optimizing CI/CD pipelines including caching strategies, parallel execution, and resource management to dramatically reduce build times.
Die Performance entscheidet ĂŒber Erfolg oder Misserfolg von XR-Erlebnissen. Ein ausgelassener Frame in VR fĂŒhrt zu Motion Sickness. Hier erfahren Sie, wie Sie Three.js fĂŒr konsistente 60fps optimieren.
import Stats from 'three/examples/jsm/libs/stats.module.js';
const stats = new Stats();
document.body.appendChild(stats.dom);
function animate() {
stats.begin();
// render
stats.end();
requestAnimationFrame(animate);
}
```text
### Render Info
```javascript
console.log(renderer.info);
// {
// memory: { geometries: 12, textures: 8 },
// render: { calls: 45, triangles: 15000, points: 0, lines: 0 }
// }
```text
## Geometrie-Optimierung
### Geometrien zusammenfĂŒhren (Merge Geometries)
```javascript
import { mergeBufferGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
const geometries = [];
for (let i = 0; i < 1000; i++) {
const geo = new THREE.BoxGeometry(1, 1, 1);
geo.translate(Math.random() * 100, 0, Math.random() * 100);
geometries.push(geo);
}
const merged = mergeBufferGeometries(geometries);
const mesh = new THREE.Mesh(merged, material);
// 1000 draw calls â 1 draw call
```text
### InstancedMesh
FĂŒr wiederkehrende, identische Objekte:
```javascript
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial();
const count = 10000;
const mesh = new THREE.InstancedMesh(geometry, material, count);
const matrix = new THREE.Matrix4();
for (let i = 0; i < count; i++) {
matrix.setPosition(
Math.random() * 100 - 50,
Math.random() * 50,
Math.random() * 100 - 50
);
mesh.setMatrixAt(i, matrix);
}
mesh.instanceMatrix.needsUpdate = true;
scene.add(mesh);
```text
## Material-Optimierung
### Materialien teilen
```javascript
// Bad: 1000 materials
for (let i = 0; i < 1000; i++) {
const mat = new THREE.MeshStandardMaterial({ color: 0xff0000 });
}
// Good: 1 shared material
const sharedMat = new THREE.MeshStandardMaterial({ color: 0xff0000 });
```text
### Ressourcenschonende Materialien verwenden
```javascript
// Most expensive
MeshPhysicalMaterial
// Medium
MeshStandardMaterial
// Cheaper
MeshLambertMaterial
// Cheapest
MeshBasicMaterial
```text
## Textur-Optimierung
### TexturgröĂe
```javascript
// Power of 2 GröĂen fĂŒr GPU-Effizienz
const loader = new THREE.TextureLoader();
const texture = loader.load('texture.jpg');
texture.encoding = THREE.sRGBEncoding;
// GroĂe Texturen anpassen
if (texture.image.width > 1024) {
// Texturkompression verwenden (KTX2, Basis)
}
```
```text
### Texture Atlasing
Combine multiple textures into one:
```javascript
// Statt 10 Materialien mit 10 Texturen
// Verwenden Sie 1 Material mit 1 Atlas-Textur
// Passen Sie die UVs pro Objekt an
```text
## Level of Detail (LOD)
```javascript
const lod = new THREE.LOD();
const highPoly = createHighPolyMesh(); // 10.000 Dreiecke
const mediumPoly = createMediumPolyMesh(); // 1.000 Dreiecke
const lowPoly = createLowPolyMesh(); // 100 Dreiecke
lod.addLevel(highPoly, 0); // Anzeigen bei 0-10 Distanz
lod.addLevel(mediumPoly, 10); // Anzeigen bei 10-50 Distanz
lod.addLevel(lowPoly, 50); // Anzeigen bei 50+ Distanz
scene.add(lod);
```text
## Frustum Culling
Three.js does this automatically, but verify:
```javascript
// PrĂŒfen, ob das Objekt sichtbar ist
const frustum = new THREE.Frustum();
const matrix = new THREE.Matrix4().multiplyMatrices(
camera.projectionMatrix,
camera.matrixWorldInverse
);
frustum.setFromProjectionMatrix(matrix);
if (frustum.intersectsObject(mesh)) {
// Objekt ist sichtbar
}
```text
## Memory Management
### Dispose Pattern
```javascript
function disposeObject(obj) {
if (obj.geometry) {
obj.geometry.dispose();
}
if (obj.material) {
if (Array.isArray(obj.material)) {
obj.material.forEach(m => disposeMaterial(m));
} else {
disposeMaterial(obj.material);
}
}
}
function disposeMaterial(mat) {
if (mat.map) mat.map.dispose();
if (mat.normalMap) mat.normalMap.dispose();
if (mat.roughnessMap) mat.roughnessMap.dispose();
mat.dispose();
}
```text
### Object Pooling
```javascript
class ObjectPool {
constructor(createFn, maxSize = 100) {
this.pool = [];
this.createFn = createFn;
this.maxSize = maxSize;
}
get() {
return this.pool.pop() | | this.createFn();
}
release(obj) {
if (this.pool.length < this.maxSize) {
obj.visible = false;
this.pool.push(obj);
} else {
disposeObject(obj);
}
}
}
```text
## Web Worker Offloading
Move heavy computation off the main thread:
```javascript
// worker.js
self.onmessage = (e) => {
const { positions, velocities } = e.data;
for (let i = 0; i < positions.length; i++) {
positions[i] += velocities[i];
}
self.postMessage({ positions });
};
// main.js
const worker = new Worker('worker.js');
worker.postMessage({ positions, velocities });
worker.onmessage = (e) => {
geometry.attributes.position.array = e.data.positions;
geometry.attributes.position.needsUpdate = true;
};
```text
## Performance Targets
| Platform | Target FPS | Draw Calls | Triangles |
| ---------- | ------------ | ------------ | ----------- |
| Desktop | 60 | < 2000 | < 10M |
| Mobile | 60 | < 500 | < 1M |
| VR Standalone | 72 | < 300 | < 500K |
| Mobile VR | 72 | < 100 | < 200K |
## Conclusion
Optimization is iterative. Profile, identify bottlenecks, optimize the biggest gains first. Geometry merging and instancing give the biggest improvements for typical scenes.