Awesome-omni-skill three-best-practices
Three.js performance optimization and best practices guidelines. Use when writing, reviewing, or optimizing Three.js code. Triggers on tasks involving 3D scenes, WebGL/WebGPU rendering, geometries, materials, textures, lighting, shaders, or TSL.
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/fullstack-web/three-best-practices" ~/.claude/skills/diegosouzapw-awesome-omni-skill-three-best-practices && rm -rf "$T"
manifest:
skills/fullstack-web/three-best-practices/SKILL.mdsource content
Three.js Best Practices
Comprehensive performance optimization guide for Three.js applications. Contains 100+ rules across 17 categories, prioritized by impact.
Based on official guidelines from Three.js
branch maintained by mrdoob.llms
When to Apply
Reference these guidelines when:
- Setting up a new Three.js project
- Writing or reviewing Three.js code
- Optimizing performance or fixing memory leaks
- Working with custom shaders (GLSL or TSL)
- Implementing WebGPU features
- Building VR/AR experiences with WebXR
- Integrating physics engines
- Optimizing for mobile devices
Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 0 | Modern Setup & Imports | FUNDAMENTAL | |
| 1 | Memory Management & Dispose | CRITICAL | |
| 2 | Render Loop Optimization | CRITICAL | |
| 3 | Geometry & Buffer Management | HIGH | |
| 4 | Material & Texture Optimization | HIGH | |
| 5 | Lighting & Shadows | MEDIUM-HIGH | |
| 6 | Scene Graph Organization | MEDIUM | |
| 7 | Shader Best Practices (GLSL) | MEDIUM | |
| 8 | TSL (Three.js Shading Language) | MEDIUM | |
| 9 | Loading & Assets | MEDIUM | |
| 10 | Camera & Controls | LOW-MEDIUM | |
| 11 | Animation System | MEDIUM | |
| 12 | Physics Integration | MEDIUM | |
| 13 | WebXR / VR / AR | MEDIUM | |
| 14 | Audio | LOW-MEDIUM | |
| 15 | Mobile Optimization | HIGH | |
| 16 | Production | HIGH | , |
| 17 | Debug & DevTools | LOW | |
Quick Reference
0. Modern Setup (FUNDAMENTAL)
- Use Import Maps, not old CDN scriptssetup-use-import-maps
- WebGLRenderer (default) vs WebGPURenderer (TSL/compute)setup-choose-renderer
- Usesetup-animation-loop
not manual RAFrenderer.setAnimationLoop()
- Complete modern scene templatesetup-basic-scene-template
1. Memory Management (CRITICAL)
- Always dispose geometriesmemory-dispose-geometry
- Always dispose materials and texturesmemory-dispose-material
- Dispose dynamically created texturesmemory-dispose-textures
- Always dispose WebGLRenderTargetmemory-dispose-render-targets
- Use recursive disposal for hierarchiesmemory-dispose-recursive
- Dispose in React cleanup/unmountmemory-dispose-on-unmount
- Dispose renderer when destroying viewmemory-renderer-dispose
- Reuse geometries and materialsmemory-reuse-objects
2. Render Loop (CRITICAL)
- Single requestAnimationFrame looprender-single-raf
- Render on demand for static scenesrender-conditional
- Use delta time for animationsrender-delta-time
- Never allocate in render looprender-avoid-allocations
- Cache expensive computationsrender-cache-computations
- Enable frustum cullingrender-frustum-culling
- Disable auto matrix updates for static objectsrender-update-matrix-manual
- Limit pixel ratio to 2render-pixel-ratio
- Use antialiasing judiciouslyrender-antialias-wisely
3. Geometry (HIGH)
- Always use BufferGeometrygeometry-buffer-geometry
- Merge static geometriesgeometry-merge-static
- Use InstancedMesh for identical objectsgeometry-instanced-mesh
- Use Level of Detail for complex modelsgeometry-lod
- Use indexed geometrygeometry-index-buffer
- Minimize vertex countgeometry-vertex-count
- Use appropriate typed arraysgeometry-attributes-typed
- Consider interleaved buffersgeometry-interleaved
4. Materials & Textures (HIGH)
- Reuse materials across meshesmaterial-reuse
- Use simplest material that worksmaterial-simplest-sufficient
- Power-of-two texture dimensionsmaterial-texture-size-power-of-two
- Use compressed textures (KTX2/Basis)material-texture-compression
- Enable mipmaps appropriatelymaterial-texture-mipmaps
- Use anisotropic filtering for floorsmaterial-texture-anisotropy
- Use texture atlasesmaterial-texture-atlas
- Minimize transparent materialsmaterial-avoid-transparency
- Use onBeforeCompile for shader mods (or TSL)material-onbeforecompile
5. Lighting & Shadows (MEDIUM-HIGH)
- Minimize dynamic lightslighting-limit-lights
- Bake lighting for static sceneslighting-bake-static
- Fit shadow camera tightlylighting-shadow-camera-tight
- Choose appropriate shadow resolutionlighting-shadow-map-size
- Enable shadows selectivelylighting-shadow-selective
- Use CSM for large sceneslighting-shadow-cascade
- Use Light Probeslighting-probe
6. Scene Graph (MEDIUM)
- Use Groups for organizationscene-group-objects
- Use Layers for selective renderingscene-layers
- Use visible flag, not add/removescene-visible-toggle
- Flatten static hierarchiesscene-flatten-static
- Name objects for debuggingscene-name-objects
- Use object poolingscene-object-pooling
7. Shaders GLSL (MEDIUM)
- Use appropriate precisionshader-precision
- Minimize branchingshader-avoid-branching
- Precompute on CPUshader-precompute-cpu
- Avoid discard, use alphaTestshader-avoid-discard
- Use textureLod for known mip levelsshader-texture-lod
- Prefer uniform arraysshader-uniform-arrays
- Use flat when appropriateshader-varying-interpolation
- Use Three.js shader chunksshader-chunk-injection
8. TSL - Three.js Shading Language (MEDIUM)
- Use TSL instead of onBeforeCompiletsl-why-use
- WebGPU setup for TSLtsl-setup-webgpu
- Full TSL type system and functionstsl-complete-reference
- Material node properties referencetsl-material-slots
- Use NodeMaterial classestsl-node-materials
- Types, operations, swizzlingtsl-basic-operations
- Creating TSL functions with Fn()tsl-functions
- If, select, loops in TSLtsl-conditionals
- Textures and triplanar mappingtsl-textures
- bloom, blur, dof, aotsl-post-processing
- GPGPU and compute operationstsl-compute-shaders
- GLSL to TSL translationtsl-glsl-to-tsl
9. Loading & Assets (MEDIUM)
- Use Draco for large meshesloading-draco-compression
- Use glTF formatloading-gltf-preferred
- Full loader setup with DRACO/Meshopt/KTX2gltf-loading-optimization
- Show loading progressloading-progress-feedback
- Use async/await for loadingloading-async-await
- Lazy load non-critical assetsloading-lazy
- Enable cachingloading-cache-assets
- Unload unused assetsloading-dispose-unused
10. Camera & Controls (LOW-MEDIUM)
- Set tight near/far planescamera-near-far
- Choose appropriate FOVcamera-fov
- Use damping for smooth controlscamera-controls-damping
- Handle resize properlycamera-resize-handler
- Set orbit control limitscamera-orbit-limits
11. Animation (MEDIUM)
- AnimationMixer, blending, morph targets, skeletalanimation-system
12. Physics (MEDIUM)
- Rapier, Cannon-es integration patternsphysics-integration
13. WebXR (MEDIUM)
- VR/AR buttons, controllers, hit testingwebxr-setup
14. Audio (LOW-MEDIUM)
- PositionalAudio, HRTF, spatial soundaudio-spatial
15. Optimization (HIGH)
- Mobile-specific optimizations and checklistmobile-optimization
- BVH, layers, GPU pickingraycasting-optimization
16. Production (HIGH)
- WebGL context loss and recoveryerror-handling-recovery
- Breaking changes by versionmigration-checklist
17. Debug (LOW)
- Use Stats.jsdebug-stats
- Use built-in helpersdebug-helpers
- Use lil-gui for tweakingdebug-gui
- Check renderer.infodebug-renderer-info
- Remove debug code in productiondebug-conditional
How to Use
Read individual rule files for detailed explanations and code examples:
rules/setup-use-import-maps.md rules/memory-dispose-geometry.md rules/tsl-complete-reference.md rules/mobile-optimization.md
Each rule file contains:
- Brief explanation of why it matters
- BAD code example with explanation
- GOOD code example with explanation
- Additional context and references
Key Patterns
Modern Import Maps
<script type="importmap"> { "imports": { "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js", "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/", "three/tsl": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.tsl.js" } } </script>
Proper Disposal
function disposeObject(obj) { if (obj.geometry) obj.geometry.dispose(); if (obj.material) { if (Array.isArray(obj.material)) { obj.material.forEach(m => m.dispose()); } else { obj.material.dispose(); } } }
TSL Basic Usage
import { texture, uv, color, time, sin } from 'three/tsl'; const material = new THREE.MeshStandardNodeMaterial(); material.colorNode = texture(map).mul(color(0xff0000)); material.colorNode = color(0x00ff00).mul(sin(time).mul(0.5).add(0.5));
Mobile Detection
const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent); renderer.setPixelRatio(Math.min(window.devicePixelRatio, isMobile ? 1.5 : 2));