Agent 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 this agent skill to your Project
npx add-skill https://github.com/emalorenzo/three-agent-skills/tree/main/skills/three-best-practices
Metadata
Additional technical details for this skill
- author
- three-agent-skills
- version
- 2.1.0
- three version
- 0.182.0+
SKILL.md
Three.js Best Practices
Comprehensive performance optimization guide for Three.js applications. Contains 120+ rules across 18 categories, prioritized by impact.
Sources & Credits
This skill compiles best practices from multiple authoritative sources:
- Official guidelines from Three.js
llmsbranch maintained by mrdoob- 100 Three.js Tips by Utsubo - Excellent comprehensive guide covering WebGPU, asset optimization, and performance tips
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 | setup- |
| 1 | Memory Management & Dispose | CRITICAL | memory- |
| 2 | Render Loop Optimization | CRITICAL | render- |
| 3 | Draw Call Optimization | CRITICAL | drawcall- |
| 4 | Geometry & Buffer Management | HIGH | geometry- |
| 5 | Material & Texture Optimization | HIGH | material- |
| 6 | Asset Compression | HIGH | asset- |
| 7 | Lighting & Shadows | MEDIUM-HIGH | lighting- |
| 8 | Scene Graph Organization | MEDIUM | scene- |
| 9 | Shader Best Practices (GLSL) | MEDIUM | shader- |
| 10 | TSL (Three.js Shading Language) | MEDIUM | tsl- |
| 11 | WebGPU Renderer | MEDIUM | webgpu- |
| 12 | Loading & Assets | MEDIUM | loading- |
| 13 | Core Web Vitals | MEDIUM-HIGH | vitals- |
| 14 | Camera & Controls | LOW-MEDIUM | camera- |
| 15 | Animation System | MEDIUM | animation- |
| 16 | Physics Integration | MEDIUM | physics- |
| 17 | WebXR / VR / AR | MEDIUM | webxr- |
| 18 | Audio | LOW-MEDIUM | audio- |
| 19 | Post-Processing | MEDIUM | postpro- |
| 20 | Mobile Optimization | HIGH | mobile- |
| 21 | Production | HIGH | error-, migration- |
| 22 | Debug & DevTools | LOW | debug- |
Quick Reference
0. Modern Setup (FUNDAMENTAL)
setup-use-import-maps- Use Import Maps, not old CDN scriptssetup-choose-renderer- WebGLRenderer (default) vs WebGPURenderer (TSL/compute)setup-animation-loop- Userenderer.setAnimationLoop()not manual RAFsetup-basic-scene-template- Complete modern scene template
1. Memory Management (CRITICAL)
memory-dispose-geometry- Always dispose geometriesmemory-dispose-material- Always dispose materials and texturesmemory-dispose-textures- Dispose dynamically created texturesmemory-dispose-render-targets- Always dispose WebGLRenderTargetmemory-dispose-recursive- Use recursive disposal for hierarchiesmemory-dispose-on-unmount- Dispose in React cleanup/unmountmemory-renderer-dispose- Dispose renderer when destroying viewmemory-reuse-objects- Reuse geometries and materials
2. Render Loop (CRITICAL)
render-single-raf- Single requestAnimationFrame looprender-conditional- Render on demand for static scenesrender-delta-time- Use delta time for animationsrender-avoid-allocations- Never allocate in render looprender-cache-computations- Cache expensive computationsrender-frustum-culling- Enable frustum cullingrender-update-matrix-manual- Disable auto matrix updates for static objectsrender-pixel-ratio- Limit pixel ratio to 2render-antialias-wisely- Use antialiasing judiciously
3. Draw Call Optimization (CRITICAL)
draw-call-optimization- Target under 100 draw calls per framegeometry-instanced-mesh- Use InstancedMesh for identical objectsgeometry-batched-mesh- Use BatchedMesh for varied geometries (same material)geometry-merge-static- Merge static geometries with BufferGeometryUtils
4. Geometry (HIGH)
geometry-buffer-geometry- Always use BufferGeometrygeometry-merge-static- Merge static geometriesgeometry-instanced-mesh- Use InstancedMesh for identical objectsgeometry-lod- Use Level of Detail for complex modelsgeometry-index-buffer- Use indexed geometrygeometry-vertex-count- Minimize vertex countgeometry-attributes-typed- Use appropriate typed arraysgeometry-interleaved- Consider interleaved buffers
5. Materials & Textures (HIGH)
material-reuse- Reuse materials across meshesmaterial-simplest-sufficient- Use simplest material that worksmaterial-texture-size-power-of-two- Power-of-two texture dimensionsmaterial-texture-compression- Use compressed textures (KTX2/Basis)material-texture-mipmaps- Enable mipmaps appropriatelymaterial-texture-anisotropy- Use anisotropic filtering for floorsmaterial-texture-atlas- Use texture atlasesmaterial-avoid-transparency- Minimize transparent materialsmaterial-onbeforecompile- Use onBeforeCompile for shader mods (or TSL)
6. Asset Compression (HIGH)
asset-compression- Draco, Meshopt, KTX2 compression guideasset-draco- 90-95% geometry size reductionasset-ktx2- GPU-compressed textures (UASTC vs ETC1S)asset-meshopt- Alternative to Draco with faster decompressionasset-lod- Level of Detail for 30-40% frame rate improvement
7. Lighting & Shadows (MEDIUM-HIGH)
lighting-limit-lights- Limit to 3 or fewer active lightslighting-shadows-advanced- PointLight cost, CSM, fake shadowslighting-bake-static- Bake lighting for static sceneslighting-shadow-camera-tight- Fit shadow camera tightlylighting-shadow-map-size- Choose appropriate shadow resolution (512-4096)lighting-shadow-selective- Enable shadows selectivelylighting-shadow-cascade- Use CSM for large sceneslighting-shadow-auto-update- Disable autoUpdate for static sceneslighting-probe- Use Light Probeslighting-environment- Environment maps for ambient lightlighting-fake-shadows- Gradient planes for budget contact shadows
8. Scene Graph (MEDIUM)
scene-group-objects- Use Groups for organizationscene-layers- Use Layers for selective renderingscene-visible-toggle- Use visible flag, not add/removescene-flatten-static- Flatten static hierarchiesscene-name-objects- Name objects for debuggingobject-pooling- Reuse objects instead of create/destroy
9. Shaders GLSL (MEDIUM)
shader-precision- Use mediump for mobile (~2x faster)shader-mobile- Mobile-specific optimizations (varyings, branching)shader-avoid-branching- Replace conditionals with mix/stepshader-precompute-cpu- Precompute on CPUshader-avoid-discard- Avoid discard, use alphaTestshader-texture-lod- Use textureLod for known mip levelsshader-uniform-arrays- Prefer uniform arraysshader-varying-interpolation- Limit varyings to 3 for mobileshader-pack-data- Pack data into RGBA channelsshader-chunk-injection- Use Three.js shader chunks
10. TSL - Three.js Shading Language (MEDIUM)
tsl-why-use- Use TSL instead of onBeforeCompiletsl-setup-webgpu- WebGPU setup for TSLtsl-complete-reference- Full TSL type system and functionstsl-material-slots- Material node properties referencetsl-node-materials- Use NodeMaterial classestsl-basic-operations- Types, operations, swizzlingtsl-functions- Creating TSL functions with Fn()tsl-conditionals- If, select, loops in TSLtsl-textures- Textures and triplanar mappingtsl-noise- Built-in noise functions (mx_noise_float, mx_fractal_noise)tsl-post-processing- bloom, blur, dof, aotsl-compute-shaders- GPGPU and compute operationstsl-glsl-to-tsl- GLSL to TSL translation
11. WebGPU Renderer (MEDIUM)
webgpu-renderer- Setup, browser support, migration guidewebgpu-render-async- Use renderAsync for compute-heavy sceneswebgpu-feature-detection- Check adapter featureswebgpu-instanced-array- GPU-persistent bufferswebgpu-storage-textures- Read-write compute textureswebgpu-workgroup-memory- Shared memory (10-100x faster)webgpu-indirect-draws- GPU-driven rendering
12. Loading & Assets (MEDIUM)
loading-draco-compression- Use Draco for large meshesloading-gltf-preferred- Use glTF formatgltf-loading-optimization- Full loader setup with DRACO/Meshopt/KTX2loading-progress-feedback- Show loading progressloading-async-await- Use async/await for loadingloading-lazy- Lazy load non-critical assetsloading-cache-assets- Enable cachingloading-dispose-unused- Unload unused assets
13. Core Web Vitals (MEDIUM-HIGH)
core-web-vitals- LCP, FID, CLS optimization for 3Dvitals-lazy-load- Lazy load 3D below the fold with IntersectionObservervitals-code-split- Dynamic import Three.js modulesvitals-preload- Preload critical assets with link tagsvitals-progressive-loading- Low-res to high-res progressive loadvitals-placeholders- Show placeholder geometry during loadvitals-web-workers- Offload heavy work to workersvitals-streaming- Stream large scenes by chunks
14. Camera & Controls (LOW-MEDIUM)
camera-near-far- Set tight near/far planescamera-fov- Choose appropriate FOVcamera-controls-damping- Use damping for smooth controlscamera-resize-handler- Handle resize properlycamera-orbit-limits- Set orbit control limits
15. Animation (MEDIUM)
animation-system- AnimationMixer, blending, morph targets, skeletal
16. Physics (MEDIUM)
physics-integration- Rapier, Cannon-es integration patternsphysics-compute-shaders- GPU physics with compute shaders
17. WebXR (MEDIUM)
webxr-setup- VR/AR buttons, controllers, hit testing
18. Audio (LOW-MEDIUM)
audio-spatial- PositionalAudio, HRTF, spatial sound
19. Post-Processing (MEDIUM)
postprocessing-optimization- pmndrs/postprocessing guidepostpro-renderer-config- Disable AA, stencil, depth for postpostpro-merge-effects- Combine effects in single passpostpro-selective-bloom- Selective bloom for performancepostpro-resolution-scaling- Half resolution for 2x FPSpostpro-webgpu-native- TSL-based post for WebGPU
20. Optimization (HIGH)
mobile-optimization- Mobile-specific optimizations and checklistraycasting-optimization- BVH, layers, GPU picking
21. Production (HIGH)
error-handling-recovery- WebGL context loss and recoverymigration-checklist- Breaking changes by version
22. Debug & DevTools (LOW)
debug-devtools- Complete debugging toolkitdebug-stats-gl- stats-gl for WebGL/WebGPU monitoringdebug-lil-gui- lil-gui for live parameter tweakingdebug-spector- Spector.js for WebGL frame capturedebug-renderer-info- Monitor draw calls and memorydebug-three-mesh-bvh- Fast raycasting with BVHdebug-context-lost- Handle WebGL context lossdebug-animation-loop-profiling- Profile render loop sectionsdebug-conditional- Remove debug code in production
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));
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
r3f-best-practices
React Three Fiber (R3F) and Poimandres ecosystem best practices. Use when writing, reviewing, or optimizing R3F code. Triggers on tasks involving @react-three/fiber, @react-three/drei, zustand, @react-three/postprocessing, @react-three/rapier, or leva.
setup-pre-commit
Set up Husky pre-commit hooks with lint-staged (Prettier), type checking, and tests in the current repo. Use when user wants to add pre-commit hooks, set up Husky, configure lint-staged, or add commit-time formatting/typechecking/testing.
handoff
Compact the current conversation into a handoff document for another agent to pick up.
scaffold-exercises
Create exercise directory structures with sections, problems, solutions, and explainers that pass linting. Use when user wants to scaffold exercises, create exercise stubs, or set up a new course section.
obsidian-vault
Search, create, and manage notes in the Obsidian vault with wikilinks and index notes. Use when user wants to find, create, or organize notes in Obsidian.
edit-article
Edit and improve articles by restructuring sections, improving clarity, and tightening prose. Use when user wants to edit, revise, or improve an article draft.
Didn't find tool you were looking for?