Resources Panel
The Resources panel provides lifecycle tracking for all GPU resources, helping identify memory leaks, orphaned objects, and resource management issues.
Overview
// Access via the Performance panel's Resources tab
overlay.showPanel('stats');
// Then click the "Resources" tab2
3
The Resources panel monitors the complete lifecycle of three.js resources:
- Creation tracking - When resources are allocated
- Disposal monitoring - When resources are freed
- Leak detection - Resources not properly disposed
- Lifecycle timeline - Visual event history
- Reference counting - Track resource usage
Panel Layout
┌─────────────────────────────────────────────────────────────────┐
│ Resources ─ □ ✕ │
├─────────────────────────────────────────────────────────────────┤
│ [All] [Textures] [Geometries] [Materials] [RenderTargets] │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Session Summary │
│ ┌─────────┬─────────┬─────────┬─────────┐ │
│ │ Created │ Disposed│ Active │ Leaked │ │
│ │ 145 │ 42 │ 103 │ 0 ✓ │ │
│ └─────────┴─────────┴─────────┴─────────┘ │
│ │
│ ═══════════════════════════════════════════════════════════ │
│ Lifecycle Timeline │
│ ───────────────────────────────────────────────────────────── │
│ │ ● ● ● ● ○ ● ● ○ ● ● ● ● ○ ○ ● │ │
│ │ ↑create ↑dispose │ │
│ ───────────────────────────────────────────────────────────── │
│ │
│ Recent Events │
│ ├─ 🟢 12:34:56.123 Texture created "env_hdr" │
│ ├─ 🟢 12:34:56.100 Geometry created "PlayerMesh" │
│ ├─ 🔴 12:34:55.890 Material disposed "OldMaterial" │
│ ├─ 🟢 12:34:55.800 RenderTarget created "SSAO_Buffer" │
│ └─ ... 141 more events │
│ │
│ ⚠️ Potential Leaks (0) │
│ ✓ No leaked resources detected │
│ │
└─────────────────────────────────────────────────────────────────┘2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Session Summary
Resource Counts
┌─────────────────────────────────────────────────────┐
│ Created Disposed Active Leaked │
│ 145 42 103 0 ✓ │
│ │
│ Balance: +103 (net resources in memory) │
└─────────────────────────────────────────────────────┘2
3
4
5
6
Indicators:
- 🟢
0leaked - All resources properly managed - 🟡
< 5leaked - Minor leaks, review recommended - 🔴
≥ 5leaked - Significant leaks, action needed
By Resource Type
Resource Breakdown:
┌──────────────┬─────────┬──────────┬────────┬────────┐
│ Type │ Created │ Disposed │ Active │ Leaked │
├──────────────┼─────────┼──────────┼────────┼────────┤
│ Textures │ 45 │ 12 │ 33 │ 0 │
│ Geometries │ 38 │ 15 │ 23 │ 0 │
│ Materials │ 52 │ 10 │ 42 │ 0 │
│ RenderTargets│ 10 │ 5 │ 5 │ 0 │
└──────────────┴─────────┴──────────┴────────┴────────┘2
3
4
5
6
7
8
9
Lifecycle Timeline
Visual Timeline
Timeline (last 60 seconds):
─────────────────────────────────────────────────────────────
│ ●●●● ○ ●● ○ ●●●● ○○ ●│ Now
│ │
│ ● = create ○ = dispose │
─────────────────────────────────────────────────────────────
↑ ↑
Scene load Dynamic unload2
3
4
5
6
7
8
Event Categories
| Event | Symbol | Color | Description |
|---|---|---|---|
| Create | ● | 🟢 Green | Resource allocated |
| Dispose | ○ | 🔴 Red | Resource freed |
| Leak | ⚠ | 🟡 Yellow | Potential leak detected |
| Error | ✕ | 🔴 Red | Disposal error |
Hover Details
Hover over timeline markers for details:
┌─────────────────────────────────────────────┐
│ Resource Created │
│ Time: 12:34:56.123 │
│ Type: Texture │
│ Name: player_diffuse │
│ Size: 2048×2048 │
│ Memory: 16 MB │
│ Stack: Scene.js:45 → Loader.js:123 │
└─────────────────────────────────────────────┘2
3
4
5
6
7
8
9
Recent Events Log
Event List
Recent Events (showing 20 of 145):
🟢 12:34:56.123 Texture created
name: "env_hdr"
size: 1024×1024
memory: 4 MB
🟢 12:34:56.100 Geometry created
name: "PlayerMesh"
vertices: 12,450
memory: 2.4 MB
🔴 12:34:55.890 Material disposed
name: "OldMaterial"
type: MeshStandardMaterial
freed: 0.1 MB
🟢 12:34:55.800 RenderTarget created
name: "SSAO_Buffer"
size: 1920×1080
memory: 8 MB2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Event Filtering
Filter events by:
- Type: Textures, Geometries, Materials, RenderTargets
- Action: Create, Dispose, Leak
- Time Range: Last minute, session, custom
- Search: By name or UUID
[All ▼] [Create ▼] [Last 5 min ▼] [Search...]Leak Detection
How Leaks Are Detected
Resources are flagged as potential leaks when:
- Removed from scene but not disposed - Object removed but
.dispose()not called - Orphaned textures - Textures no longer referenced by any material
- Orphaned geometries - Geometries no longer used by any mesh
- Stale render targets - Render targets from removed post-processing passes
Leak Alerts
┌─────────────────────────────────────────────────────────────────┐
│ ⚠️ Potential Leaks Detected (3) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 🟡 Texture: "enemy_diffuse" │
│ Created: 5 minutes ago │
│ Last referenced: 3 minutes ago │
│ Memory: 8 MB │
│ Status: No material references │
│ [Dispose] [Ignore] [Details] │
│ │
│ 🟡 Geometry: "BulletMesh" │
│ Created: 2 minutes ago │
│ Last referenced: 1 minute ago │
│ Memory: 0.5 MB │
│ Status: No mesh references (was removed from scene) │
│ [Dispose] [Ignore] [Details] │
│ │
│ 🟡 RenderTarget: "OldBloom_Buffer" │
│ Created: 10 minutes ago │
│ Memory: 4 MB │
│ Status: Not used in render pipeline │
│ [Dispose] [Ignore] [Details] │
│ │
│ Total Leaked Memory: ~12.5 MB │
│ [Dispose All Leaks] │
└─────────────────────────────────────────────────────────────────┘2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Leak Report
Generate a detailed leak report:
interface LeakReport {
timestamp: number;
totalLeaks: number;
totalLeakedMemory: number;
leaks: LeakAlert[];
}
interface LeakAlert {
resourceType: 'texture' | 'geometry' | 'material' | 'renderTarget';
resourceId: string;
name: string;
createdAt: number;
lastReferencedAt: number;
estimatedMemory: number;
reason: string;
stackTrace?: string;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Resource Details
Click to Inspect
Click any resource in the event log for details:
┌─────────────────────────────────────────────────────────────────┐
│ Texture Details [✕] │
├─────────────────────────────────────────────────────────────────┤
│ Name: player_diffuse │
│ UUID: abc123-def456-... │
│ │
│ Lifecycle: │
│ ├─ Created: 12:34:56.123 (5 min ago) │
│ ├─ Status: Active │
│ └─ References: 2 materials │
│ │
│ Properties: │
│ ├─ Size: 2048 × 2048 │
│ ├─ Format: RGBA │
│ ├─ Memory: 16 MB │
│ └─ Mipmaps: Yes │
│ │
│ Referenced By: │
│ ├─ PlayerSkin (map) │
│ └─ PlayerSkin (emissiveMap) │
│ │
│ Creation Stack Trace: │
│ ├─ loadTexture() at AssetLoader.js:45 │
│ ├─ loadPlayer() at Player.js:23 │
│ └─ init() at Game.js:100 │
│ │
│ [Open in Textures Panel] [Log to Console] [Dispose] │
└─────────────────────────────────────────────────────────────────┘2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
API Integration
Event Subscription
// Subscribe to resource lifecycle events
probe.on('resourceCreated', (event: ResourceLifecycleEvent) => {
console.log(`Created ${event.type}: ${event.name}`);
});
probe.on('resourceDisposed', (event: ResourceLifecycleEvent) => {
console.log(`Disposed ${event.type}: ${event.name}`);
});
probe.on('leakDetected', (alert: LeakAlert) => {
console.warn(`Potential leak: ${alert.name}`);
});2
3
4
5
6
7
8
9
10
11
12
Get Resource Summary
const summary: ResourceLifecycleSummary = probe.getResourceSummary();
console.log('Active textures:', summary.textures.active);
console.log('Leaked geometries:', summary.geometries.leaked);2
3
Manual Leak Check
// Trigger manual leak detection
const leaks = probe.detectLeaks();
if (leaks.length > 0) {
console.warn('Leaks found:', leaks);
}2
3
4
5
Dispose Leaked Resources
// Dispose specific leak
probe.disposeLeakedResource(leakAlert.resourceId);
// Dispose all leaks
probe.disposeAllLeaks();2
3
4
5
Configuration
Enable Stack Traces
const probe = createProbe({
tracking: {
captureStackTraces: true, // Capture creation stack traces
stackTraceDepth: 10, // Max stack depth
},
});2
3
4
5
6
Leak Detection Settings
const probe = createProbe({
leakDetection: {
enabled: true,
checkInterval: 5000, // Check every 5 seconds
graceperiod: 10000, // Wait 10s before flagging as leak
ignorePatterns: [ // Ignore specific resources
/^__internal_/,
/^debug_/,
],
},
});2
3
4
5
6
7
8
9
10
11
Common Leak Patterns
Dynamic Object Creation
// ❌ Leak: geometry not disposed
function createBullet() {
const geometry = new THREE.SphereGeometry(0.1);
const material = new THREE.MeshBasicMaterial();
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
return mesh;
}
// ✅ Fixed: dispose when removed
function removeBullet(mesh) {
scene.remove(mesh);
mesh.geometry.dispose();
mesh.material.dispose();
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
Texture Loading
// ❌ Leak: old texture not disposed
function updateTexture(mesh, newUrl) {
const texture = textureLoader.load(newUrl);
mesh.material.map = texture; // Old texture leaked!
}
// ✅ Fixed: dispose old texture
function updateTexture(mesh, newUrl) {
const oldTexture = mesh.material.map;
const newTexture = textureLoader.load(newUrl);
mesh.material.map = newTexture;
if (oldTexture) oldTexture.dispose();
}2
3
4
5
6
7
8
9
10
11
12
13
Effect Composer
// ❌ Leak: render targets not disposed
function removePostProcessing() {
composer = null; // Render targets leaked!
}
// ✅ Fixed: dispose composer properly
function removePostProcessing() {
composer.renderTarget1.dispose();
composer.renderTarget2.dispose();
composer.passes.forEach(pass => pass.dispose?.());
composer = null;
}2
3
4
5
6
7
8
9
10
11
12
Best Practices
Always dispose - Call
.dispose()when removing resourcestypescriptmesh.geometry.dispose(); mesh.material.dispose(); texture.dispose(); renderTarget.dispose();1
2
3
4Track ownership - Know which code owns each resource
Use resource pools - Reuse objects instead of creating/destroying
typescriptconst bulletPool = new ObjectPool(createBullet, 100);1Enable stack traces in development - Easier leak debugging
Regular leak checks - Run leak detection during testing
Clean up on scene transitions - Dispose all scene-specific resources