0
# Performance
1
2
Optimization components for efficient rendering of large datasets and complex scenes. These components provide various strategies for maintaining smooth framerates while handling demanding 3D content.
3
4
## Capabilities
5
6
### Instances
7
8
Instanced mesh rendering for efficiently displaying large numbers of identical objects with individual transforms.
9
10
```typescript { .api }
11
/**
12
* Instanced mesh rendering for identical objects
13
* @param props - Instances configuration
14
* @returns JSX element for instanced mesh
15
*/
16
function Instances(props: InstancesProps): JSX.Element;
17
18
/**
19
* Individual instance within an Instances component
20
* @param props - Instance configuration
21
* @returns JSX element for single instance
22
*/
23
function Instance(props: InstanceProps): JSX.Element;
24
25
interface InstancesProps extends Omit<ThreeElements['instancedMesh'], 'ref' | 'args'> {
26
/** Maximum number of instances */
27
limit?: number;
28
/** Instance range [start, count] */
29
range?: [number, number];
30
/** Frustum culling, true */
31
frustumCulled?: boolean;
32
/** Render order */
33
renderOrder?: number;
34
}
35
36
interface InstanceProps {
37
/** Instance position */
38
position?: [number, number, number];
39
/** Instance rotation */
40
rotation?: [number, number, number];
41
/** Instance scale */
42
scale?: [number, number, number] | number;
43
/** Instance color */
44
color?: ReactThreeFiber.Color;
45
/** Instance matrix */
46
matrix?: Matrix4;
47
}
48
```
49
50
**Usage Examples:**
51
52
```typescript
53
import { Instances, Instance } from '@react-three/drei';
54
55
// Basic instancing
56
<Instances limit={1000} frustumCulled>
57
<boxGeometry />
58
<meshStandardMaterial />
59
{Array.from({ length: 1000 }, (_, i) => (
60
<Instance
61
key={i}
62
position={[
63
(Math.random() - 0.5) * 100,
64
(Math.random() - 0.5) * 100,
65
(Math.random() - 0.5) * 100
66
]}
67
rotation={[Math.random(), Math.random(), Math.random()]}
68
scale={Math.random() * 0.5 + 0.5}
69
color={`hsl(${Math.random() * 360}, 50%, 50%)`}
70
/>
71
))}
72
</Instances>
73
74
// Animated instances
75
function AnimatedInstances() {
76
return (
77
<Instances limit={100}>
78
<sphereGeometry />
79
<meshNormalMaterial />
80
{Array.from({ length: 100 }, (_, i) => (
81
<AnimatedInstance key={i} index={i} />
82
))}
83
</Instances>
84
);
85
}
86
87
function AnimatedInstance({ index }) {
88
const ref = useRef();
89
90
useFrame((state) => {
91
const time = state.clock.elapsedTime;
92
const angle = (index / 100) * Math.PI * 2;
93
ref.current.position.set(
94
Math.cos(angle + time) * 10,
95
Math.sin(time) * 2,
96
Math.sin(angle + time) * 10
97
);
98
});
99
100
return <Instance ref={ref} />;
101
}
102
```
103
104
### Points
105
106
Efficient point cloud rendering using GPU-based point systems for large datasets.
107
108
```typescript { .api }
109
/**
110
* Efficient point cloud rendering with GPU processing
111
* @param props - Points configuration
112
* @returns JSX element for point cloud
113
*/
114
function Points(props: PointsProps): JSX.Element;
115
116
interface PointsProps extends Omit<ThreeElements['points'], 'ref'> {
117
/** Point positions array */
118
positions?: Float32Array | number[];
119
/** Point colors array */
120
colors?: Float32Array | number[];
121
/** Point sizes array */
122
sizes?: Float32Array | number[];
123
/** Point count limit */
124
limit?: number;
125
/** Frustum culling, true */
126
frustumCulled?: boolean;
127
}
128
129
interface PointsInstancesProps extends PointsProps {
130
/** Instanced rendering, false */
131
instances?: boolean;
132
/** Instance limit, 1000 */
133
instanceLimit?: number;
134
}
135
136
interface PointsBuffersProps extends PointsProps {
137
/** Use buffer geometry, true */
138
buffer?: boolean;
139
/** Buffer update frequency */
140
updateFrequency?: number;
141
}
142
```
143
144
**Usage Examples:**
145
146
```typescript
147
import { Points } from '@react-three/drei';
148
149
// Basic point cloud
150
function PointCloud() {
151
const pointCount = 10000;
152
const positions = new Float32Array(pointCount * 3);
153
const colors = new Float32Array(pointCount * 3);
154
155
for (let i = 0; i < pointCount; i++) {
156
// Random positions
157
positions[i * 3] = (Math.random() - 0.5) * 100;
158
positions[i * 3 + 1] = (Math.random() - 0.5) * 100;
159
positions[i * 3 + 2] = (Math.random() - 0.5) * 100;
160
161
// Random colors
162
colors[i * 3] = Math.random();
163
colors[i * 3 + 1] = Math.random();
164
colors[i * 3 + 2] = Math.random();
165
}
166
167
return (
168
<Points positions={positions} colors={colors} limit={pointCount}>
169
<pointsMaterial size={0.1} vertexColors />
170
</Points>
171
);
172
}
173
174
// Animated point cloud
175
function AnimatedPoints() {
176
const pointsRef = useRef();
177
const pointCount = 5000;
178
179
useFrame((state) => {
180
if (pointsRef.current?.geometry?.attributes?.position) {
181
const positions = pointsRef.current.geometry.attributes.position.array;
182
const time = state.clock.elapsedTime;
183
184
for (let i = 0; i < pointCount; i++) {
185
const i3 = i * 3;
186
positions[i3 + 1] += Math.sin(time + i * 0.01) * 0.01;
187
}
188
189
pointsRef.current.geometry.attributes.position.needsUpdate = true;
190
}
191
});
192
193
return (
194
<Points ref={pointsRef} limit={pointCount}>
195
<pointsMaterial size={0.05} color="hotpink" />
196
</Points>
197
);
198
}
199
```
200
201
### Detailed
202
203
Level-of-detail (LOD) rendering component that switches between different representations based on distance.
204
205
```typescript { .api }
206
/**
207
* Level-of-detail rendering based on distance
208
* @param props - LOD configuration
209
* @returns JSX element for LOD system
210
*/
211
function Detailed(props: DetailedProps): JSX.Element;
212
213
interface DetailedProps extends Omit<ThreeElements['group'], 'ref'> {
214
/** LOD distances array */
215
distances: number[];
216
/** Hysteresis factor, 0 */
217
hysteresis?: number;
218
}
219
```
220
221
**Usage Examples:**
222
223
```typescript
224
import { Detailed } from '@react-three/drei';
225
226
// LOD with multiple detail levels
227
<Detailed distances={[0, 10, 20, 35, 60]}>
228
{/* High detail - close up */}
229
<mesh>
230
<sphereGeometry args={[1, 64, 64]} />
231
<meshStandardMaterial />
232
</mesh>
233
234
{/* Medium detail */}
235
<mesh>
236
<sphereGeometry args={[1, 32, 32]} />
237
<meshStandardMaterial />
238
</mesh>
239
240
{/* Low detail */}
241
<mesh>
242
<sphereGeometry args={[1, 16, 16]} />
243
<meshStandardMaterial />
244
</mesh>
245
246
{/* Very low detail */}
247
<mesh>
248
<sphereGeometry args={[1, 8, 8]} />
249
<meshBasicMaterial />
250
</mesh>
251
252
{/* Billboard for far distances */}
253
<sprite>
254
<spriteMaterial map={billboardTexture} />
255
</sprite>
256
</Detailed>
257
```
258
259
### PerformanceMonitor
260
261
Performance monitoring system with automatic quality degradation and frame rate tracking.
262
263
```typescript { .api }
264
/**
265
* Performance monitoring with automatic degradation
266
* @param props - Performance monitor configuration
267
* @returns JSX element for performance monitoring
268
*/
269
function PerformanceMonitor(props: PerformanceMonitorProps): JSX.Element;
270
271
interface PerformanceMonitorProps {
272
/** Target FPS, 60 */
273
fps?: number;
274
/** Performance factor [0-1], 1 */
275
factor?: number;
276
/** Flip performance, false */
277
flipflops?: number;
278
/** Step size for adjustments, 1 */
279
step?: number;
280
/** Monitor enabled, true */
281
enabled?: boolean;
282
/** Performance change callback */
283
onIncline?: (api: PerformanceMonitorApi) => void;
284
/** Performance decline callback */
285
onDecline?: (api: PerformanceMonitorApi) => void;
286
/** Frame drop callback */
287
onFallback?: (api: PerformanceMonitorApi) => void;
288
}
289
290
interface PerformanceMonitorApi {
291
/** Current performance factor */
292
factor: number;
293
/** Current FPS */
294
fps: number;
295
/** Render count */
296
frames: number;
297
/** Performance monitor enabled */
298
enabled: boolean;
299
}
300
```
301
302
**Usage Examples:**
303
304
```typescript
305
import { PerformanceMonitor } from '@react-three/drei';
306
307
function AdaptiveScene() {
308
const [dpr, setDpr] = useState(1);
309
const [quality, setQuality] = useState(1);
310
311
return (
312
<>
313
<PerformanceMonitor
314
onIncline={() => {
315
setDpr(Math.min(2, dpr + 0.1));
316
setQuality(Math.min(1, quality + 0.1));
317
}}
318
onDecline={() => {
319
setDpr(Math.max(0.5, dpr - 0.1));
320
setQuality(Math.max(0.3, quality - 0.1));
321
}}
322
onFallback={() => {
323
setDpr(0.5);
324
setQuality(0.3);
325
}}
326
/>
327
328
<Canvas dpr={dpr}>
329
<AdaptiveContent quality={quality} />
330
</Canvas>
331
</>
332
);
333
}
334
```
335
336
### Preload
337
338
Asset preloading system for improving loading performance and user experience.
339
340
```typescript { .api }
341
/**
342
* Asset preloading system for better performance
343
* @param props - Preload configuration
344
* @returns JSX element for preloading assets
345
*/
346
function Preload(props: PreloadProps): JSX.Element;
347
348
interface PreloadProps {
349
/** Preload all assets, true */
350
all?: boolean;
351
/** Asset scenes to preload */
352
scene?: Object3D | Object3D[];
353
/** Preload cameras, false */
354
camera?: boolean;
355
/** Include invisible objects, false */
356
includeInvisible?: boolean;
357
}
358
```
359
360
**Usage Examples:**
361
362
```typescript
363
import { Preload } from '@react-three/drei';
364
365
// Preload all scene assets
366
<Canvas>
367
<Suspense fallback={<Loader />}>
368
<Scene />
369
<Preload all />
370
</Suspense>
371
</Canvas>
372
373
// Selective preloading
374
<Preload scene={sceneRef.current} includeInvisible />
375
```
376
377
### AdaptiveDpr
378
379
Adaptive device pixel ratio component for dynamic resolution scaling based on performance.
380
381
```typescript { .api }
382
/**
383
* Adaptive device pixel ratio for performance scaling
384
* @param props - Adaptive DPR configuration
385
* @returns JSX element for adaptive DPR
386
*/
387
function AdaptiveDpr(props: AdaptiveDprProps): JSX.Element;
388
389
interface AdaptiveDprProps {
390
/** Lower DPR bound, 1 */
391
pixelated?: number;
392
/** Upper DPR bound, 2 */
393
dpr?: number;
394
}
395
```
396
397
### AdaptiveEvents
398
399
Adaptive event handling that reduces event frequency based on performance needs.
400
401
```typescript { .api }
402
/**
403
* Adaptive event handling for performance optimization
404
* @param props - Adaptive events configuration
405
* @returns JSX element for adaptive events
406
*/
407
function AdaptiveEvents(props: AdaptiveEventsProps): JSX.Element;
408
409
interface AdaptiveEventsProps {
410
/** Event enabled, true */
411
enabled?: boolean;
412
}
413
```
414
415
### BakeShadows
416
417
Shadow map baking utility for static lighting performance optimization.
418
419
```typescript { .api }
420
/**
421
* Shadow map baking for static lighting optimization
422
* @param props - Bake shadows configuration
423
* @returns JSX element for shadow baking
424
*/
425
function BakeShadows(props: BakeShadowsProps): JSX.Element;
426
427
interface BakeShadowsProps {
428
/** Baking enabled, true */
429
enabled?: boolean;
430
}
431
```
432
433
### meshBounds
434
435
Efficient mesh bounds calculation for optimized raycasting and collision detection.
436
437
```typescript { .api }
438
/**
439
* Efficient mesh bounds calculation for raycasting optimization
440
* @param mesh - Target mesh for bounds calculation
441
* @returns Bounds helper functions
442
*/
443
function meshBounds(mesh: Mesh): {
444
raycast: (raycaster: Raycaster, intersects: Intersection[]) => void;
445
};
446
```
447
448
**Usage Examples:**
449
450
```typescript
451
import { meshBounds } from '@react-three/drei';
452
453
function OptimizedMesh() {
454
const meshRef = useRef();
455
456
useLayoutEffect(() => {
457
if (meshRef.current) {
458
// Use efficient bounds-based raycasting
459
meshRef.current.raycast = meshBounds(meshRef.current).raycast;
460
}
461
}, []);
462
463
return (
464
<mesh ref={meshRef}>
465
<complexGeometry /> {/* Complex geometry with optimized raycasting */}
466
<meshStandardMaterial />
467
</mesh>
468
);
469
}
470
```
471
472
## Integration Patterns
473
474
### Performance-Adaptive Rendering
475
476
```typescript
477
function AdaptiveScene() {
478
const [performanceLevel, setPerformanceLevel] = useState(1);
479
480
return (
481
<>
482
<PerformanceMonitor
483
onDecline={(api) => {
484
if (api.factor < 0.5) setPerformanceLevel(0.3);
485
else if (api.factor < 0.8) setPerformanceLevel(0.6);
486
}}
487
onIncline={(api) => {
488
if (api.factor > 0.9) setPerformanceLevel(1);
489
else if (api.factor > 0.7) setPerformanceLevel(0.8);
490
}}
491
/>
492
493
<AdaptiveDpr pixelated={performanceLevel} />
494
<AdaptiveEvents enabled={performanceLevel > 0.5} />
495
496
{/* Render based on performance level */}
497
{performanceLevel > 0.8 ? (
498
<HighQualityContent />
499
) : performanceLevel > 0.5 ? (
500
<MediumQualityContent />
501
) : (
502
<LowQualityContent />
503
)}
504
</>
505
);
506
}
507
```
508
509
### Instanced Forest Example
510
511
```typescript
512
function Forest() {
513
const treeCount = 1000;
514
const trees = useMemo(() => {
515
return Array.from({ length: treeCount }, (_, i) => ({
516
position: [
517
(Math.random() - 0.5) * 200,
518
0,
519
(Math.random() - 0.5) * 200
520
],
521
rotation: [0, Math.random() * Math.PI * 2, 0],
522
scale: Math.random() * 0.5 + 0.5,
523
}));
524
}, []);
525
526
return (
527
<Instances limit={treeCount} frustumCulled>
528
<cylinderGeometry args={[0.1, 0.3, 3]} />
529
<meshStandardMaterial color="brown" />
530
{trees.map((tree, i) => (
531
<Instance
532
key={i}
533
position={tree.position}
534
rotation={tree.rotation}
535
scale={tree.scale}
536
/>
537
))}
538
</Instances>
539
);
540
}
541
```
542
543
### Dynamic LOD System
544
545
```typescript
546
function DynamicLOD({ position }) {
547
const { camera } = useThree();
548
const [distance, setDistance] = useState(0);
549
550
useFrame(() => {
551
const dist = camera.position.distanceTo(new Vector3(...position));
552
setDistance(dist);
553
});
554
555
return (
556
<Detailed distances={[0, 10, 25, 50]} hysteresis={2}>
557
{/* Ultra high detail */}
558
<ComplexModel vertices={50000} />
559
560
{/* High detail */}
561
<ComplexModel vertices={10000} />
562
563
{/* Medium detail */}
564
<SimpleModel vertices={1000} />
565
566
{/* Low detail - billboard */}
567
<Billboard>
568
<Image url="/billboard.png" />
569
</Billboard>
570
</Detailed>
571
);
572
}
573
```
574
575
### Memory Management
576
577
```typescript
578
function MemoryEfficientScene() {
579
// Dispose of unused assets
580
useEffect(() => {
581
return () => {
582
// Clean up geometries
583
geometries.forEach(geo => geo.dispose());
584
// Clean up materials
585
materials.forEach(mat => mat.dispose());
586
// Clean up textures
587
textures.forEach(tex => tex.dispose());
588
};
589
}, []);
590
591
// Use object pooling for frequently created/destroyed objects
592
const objectPool = useMemo(() => new ObjectPool(), []);
593
594
return (
595
<>
596
<BakeShadows /> {/* Bake static shadows */}
597
<PooledObjects pool={objectPool} />
598
</>
599
);
600
}
601
```
602
603
### BakeShadows
604
605
Component that bakes static shadows for performance optimization.
606
607
```typescript { .api }
608
/**
609
* Bakes static shadows to improve rendering performance
610
* @returns JSX element that disables shadow auto-update
611
*/
612
function BakeShadows(): JSX.Element;
613
```
614
615
### Preload
616
617
Component for preloading and compiling shaders and materials.
618
619
```typescript { .api }
620
/**
621
* Preloads and compiles shaders and materials for smoother performance
622
* @param props - Preload configuration props
623
* @returns JSX element for preloading
624
*/
625
function Preload(props: PreloadProps): JSX.Element;
626
627
interface PreloadProps {
628
/** Preload all objects, false */
629
all?: boolean;
630
/** Scene to preload */
631
scene?: Object3D;
632
/** Camera for preloading */
633
camera?: Camera;
634
}
635
```
636
637
### meshBounds
638
639
Utility function for efficient mesh bounds calculation.
640
641
```typescript { .api }
642
/**
643
* Efficient mesh bounds calculation for culling and optimization
644
* @param mesh - Mesh to calculate bounds for
645
* @returns Bounds helper
646
*/
647
function meshBounds(mesh: Mesh): BoundsApi;
648
649
interface BoundsApi {
650
/** Get bounding box */
651
getBox(): Box3;
652
/** Get bounding sphere */
653
getSphere(): Sphere;
654
/** Check if point is inside bounds */
655
containsPoint(point: Vector3): boolean;
656
}
657
```