three-best-practices について
Three.js 開発者向けのパフォーマンス最適化ガイドです。優先度別の23カテゴリにルールとコード例をまとめ、メモリ管理から WebXR、WebGPU、モバイル最適化まで扱います。
主な機能
- 01優先度別の23ルールカテゴリ
- 02性能とメモリ管理の指針
- 03GLSL、TSL、WebGPUを網羅
- 04読み込み、アニメーション、WebXRの指針
- 05対比形式のコード例
活用シーン
- 01Three.js プロジェクトの立ち上げ
- 02Three.js コードのレビューや最適化
- 03メモリリークや性能問題の調査
- 04WebGPU または WebXR 機能の実装
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ emalorenzo/ three-agent-skills --skill three-best-practicesインストール後、Claude Code で/three-best-practicesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
rules/_sections.mdanimation-system.mdasset-compression.mdaudio-spatial.mdcore-web-vitals.mddebug-devtools.mddraw-call-optimization.mderror-handling-recovery.mdgeometry-instanced-mesh.mdgltf-loading-optimization.mdlighting-shadows-advanced.mdmemory-dispose-geometry.mdmigration-checklist.mdmobile-optimization.mdobject-pooling.mdphysics-integration.mdpostprocessing-optimization.mdraycasting-optimization.mdrender-delta-time.mdsetup-use-import-maps.mdshader-mobile.mdtsl-complete-reference.mdtsl-compute-shaders.mdtsl-material-slots.mdtsl-post-processing.mdtsl-why-use.mdwebgpu-renderer.mdwebxr-setup.md詳細
Three.js のベストプラクティス
Three.js アプリケーション向けの包括的なパフォーマンス最適化ガイドです。影響度順に優先順位付けされた、18 カテゴリーにわたる 120 以上のルールを掲載しています。
出典とクレジット
このスキルは、複数の信頼できる情報源からベストプラクティスをまとめたものです。
- mrdoob がメンテナンスする Three.js の
llmsブランチにある公式ガイドライン- Utsubo による 100 Three.js Tips — WebGPU、アセットの最適化、パフォーマンスのヒントを扱う、優れた包括的ガイド
適用する場面
以下の場面で、これらのガイドラインを参照してください。
- 新しい Three.js プロジェクトをセットアップするとき
- Three.js コードを記述またはレビューするとき
- パフォーマンスを最適化したり、メモリリークを修正したりするとき
- カスタムシェーダー(GLSL または TSL)を扱うとき
- WebGPU の機能を実装するとき
- WebXR で VR/AR エクスペリエンスを構築するとき
- 物理エンジンを統合するとき
- モバイルデバイス向けに最適化するとき
優先度別のルールカテゴリー
| 優先度 | カテゴリー | 影響度 | 接頭辞 |
|---|---|---|---|
| 0 | モダンなセットアップとインポート | FUNDAMENTAL | setup- |
| 1 | メモリ管理と破棄 | CRITICAL | memory- |
| 2 | レンダーループの最適化 | CRITICAL | render- |
| 3 | 描画呼び出しの最適化 | CRITICAL | drawcall- |
| 4 | ジオメトリとバッファーの管理 | HIGH | geometry- |
| 5 | マテリアルとテクスチャの最適化 | HIGH | material- |
| 6 | アセットの圧縮 | HIGH | asset- |
| 7 | ライティングとシャドウ | MEDIUM-HIGH | lighting- |
| 8 | シーングラフの構成 | MEDIUM | scene- |
| 9 | シェーダーのベストプラクティス(GLSL) | MEDIUM | shader- |
| 10 | TSL(Three.js Shading Language) | MEDIUM | tsl- |
| 11 | WebGPU レンダラー | MEDIUM | webgpu- |
| 12 | 読み込みとアセット | MEDIUM | loading- |
| 13 | Core Web Vitals | MEDIUM-HIGH | vitals- |
| 14 | カメラとコントロール | LOW-MEDIUM | camera- |
| 15 | アニメーションシステム | MEDIUM | animation- |
| 16 | 物理演算の統合 | MEDIUM | physics- |
| 17 | WebXR / VR / AR | MEDIUM | webxr- |
| 18 | オーディオ | LOW-MEDIUM | audio- |
| 19 | ポストプロセス | MEDIUM | postpro- |
| 20 | モバイル最適化 | HIGH | mobile- |
| 21 | 本番環境 | HIGH | error-, migration- |
| 22 | デバッグと開発者ツール | LOW | debug- |
クイックリファレンス
0. モダンなセットアップ(FUNDAMENTAL)
setup-use-import-maps- 古い CDN スクリプトではなく、Import Maps を使用するsetup-choose-renderer- WebGLRenderer(デフォルト)と WebGPURenderer(TSL/compute)を使い分けるsetup-animation-loop- 手動の RAF ではなく、renderer.setAnimationLoop()を使用するsetup-basic-scene-template- モダンなシーンの完全なテンプレート
1. メモリ管理(CRITICAL)
memory-dispose-geometry- ジオメトリは必ず破棄するmemory-dispose-material- マテリアルとテクスチャは必ず破棄するmemory-dispose-textures- 動的に作成したテクスチャを破棄するmemory-dispose-render-targets- WebGLRenderTarget は必ず破棄するmemory-dispose-recursive- 階層構造には再帰的な破棄を使用するmemory-dispose-on-unmount- React のクリーンアップ/アンマウント時に破棄するmemory-renderer-dispose- ビューを破棄するときにレンダラーを破棄するmemory-reuse-objects- ジオメトリとマテリアルを再利用する
2. レンダーループ(CRITICAL)
render-single-raf- requestAnimationFrame ループを 1 つだけ使用するrender-conditional- 静的なシーンは必要に応じてレンダリングするrender-delta-time- アニメーションにはデルタタイムを使用するrender-avoid-allocations- レンダーループ内ではメモリを割り当てないrender-cache-computations- コストの高い計算結果をキャッシュするrender-frustum-culling- 視錐台カリングを有効にするrender-update-matrix-manual- 静的オブジェクトでは行列の自動更新を無効にするrender-pixel-ratio- ピクセル比を 2 に制限するrender-antialias-wisely- アンチエイリアスは適切に使用する
3. 描画コールの最適化(最重要)
draw-call-optimization- 1 フレームあたりの描画コール数を 100 未満に抑えますgeometry-instanced-mesh- 同一オブジェクトには InstancedMesh を使用しますgeometry-batched-mesh- ジオメトリが異なる場合は、同じマテリアルで BatchedMesh を使用しますgeometry-merge-static- BufferGeometryUtils で静的ジオメトリを結合します
4. ジオメトリ(重要)
geometry-buffer-geometry- 常に BufferGeometry を使用しますgeometry-merge-static- 静的ジオメトリを結合しますgeometry-instanced-mesh- 同一オブジェクトには InstancedMesh を使用しますgeometry-lod- 複雑なモデルには Level of Detail を使用しますgeometry-index-buffer- インデックス付きジオメトリを使用しますgeometry-vertex-count- 頂点数を最小限に抑えますgeometry-attributes-typed- 適切な型付き配列を使用しますgeometry-interleaved- インターリーブバッファを検討します
5. マテリアルとテクスチャ(重要)
material-reuse- 複数のメッシュでマテリアルを再利用しますmaterial-simplest-sufficient- 目的を満たす最もシンプルなマテリアルを使用しますmaterial-texture-size-power-of-two- テクスチャの寸法を 2 の累乗にしますmaterial-texture-compression- 圧縮テクスチャ(KTX2/Basis)を使用しますmaterial-texture-mipmaps- 適切にミップマップを有効にしますmaterial-texture-anisotropy- 床には異方性フィルタリングを使用しますmaterial-texture-atlas- テクスチャアトラスを使用しますmaterial-avoid-transparency- 透明マテリアルを最小限に抑えますmaterial-onbeforecompile- シェーダーの変更には onBeforeCompile(または TSL)を使用します
6. アセット圧縮(重要)
asset-compression- Draco、Meshopt、KTX2 の圧縮ガイドasset-draco- ジオメトリのサイズを 90~95% 削減しますasset-ktx2- GPU 圧縮テクスチャ(UASTC と ETC1S)asset-meshopt- Draco の代替手段で、より高速に展開できますasset-lod- Level of Detail によりフレームレートを 30~40% 向上させます
7. ライティングとシャドウ(中~高)
lighting-limit-lights- 有効なライトを 3 個以下に制限しますlighting-shadows-advanced- PointLight のコスト、CSM、擬似シャドウlighting-bake-static- 静的なシーンではライティングをベイクしますlighting-shadow-camera-tight- シャドウカメラの範囲を適切に絞りますlighting-shadow-map-size- 適切なシャドウ解像度(512-4096)を選択しますlighting-shadow-selective- シャドウを選択的に有効にしますlighting-shadow-cascade- 大規模なシーンでは CSM を使用しますlighting-shadow-auto-update- 静的なシーンでは autoUpdate を無効にしますlighting-probe- Light Probes を使用しますlighting-environment- 環境マップで環境光を表現しますlighting-fake-shadows- 負荷を抑えた接地シャドウにはグラデーション付きの平面を使用します
8. シーングラフ(中)
scene-group-objects- 整理には Groups を使用しますscene-layers- 選択的なレンダリングには Layers を使用しますscene-visible-toggle- 追加・削除ではなく visible フラグを使用しますscene-flatten-static- 静的な階層をフラット化しますscene-name-objects- デバッグ用にオブジェクトに名前を付けますobject-pooling- オブジェクトを生成・破棄するのではなく再利用します
9. シェーダー GLSL(中)
shader-precision- モバイルでは mediump を使用します(約 2 倍高速)shader-mobile- モバイル向けに最適化します(varyings、分岐)shader-avoid-branching- 条件分岐を mix/step に置き換えますshader-precompute-cpu- CPU 上で事前計算しますshader-avoid-discard- discard を避け、alphaTest を使用しますshader-texture-lod- ミップレベルが既知の場合は textureLod を使用しますshader-uniform-arrays- uniform 配列を優先して使用しますshader-varying-interpolation- モバイルでは varyings を 3 個までに制限しますshader-pack-data- データを RGBA チャネルにパックしますshader-chunk-injection- Three.js のシェーダーチャンクを使用します
10. TSL - Three.js Shading Language(中程度)
tsl-why-use- onBeforeCompile の代わりに TSL を使うtsl-setup-webgpu- TSL 用の WebGPU セットアップtsl-complete-reference- TSL の型システムと関数の完全なリファレンスtsl-material-slots- マテリアルノードのプロパティリファレンスtsl-node-materials- NodeMaterial クラスを使うtsl-basic-operations- 型、演算、スウィズリングtsl-functions- Fn() を使った TSL 関数の作成tsl-conditionals- TSL での If、select、ループtsl-textures- テクスチャとトライプラナー マッピングtsl-noise- 組み込みノイズ関数(mx_noise_float、mx_fractal_noise)tsl-post-processing- ブルーム、ぼかし、被写界深度、AOtsl-compute-shaders- GPGPU とコンピュート処理tsl-glsl-to-tsl- GLSL から TSL への変換
11. WebGPU レンダラー(中程度)
webgpu-renderer- セットアップ、ブラウザー対応、移行ガイドwebgpu-render-async- コンピュート負荷の高いシーンで renderAsync を使うwebgpu-feature-detection- アダプターの機能を確認するwebgpu-instanced-array- GPU 上に永続化するバッファーwebgpu-storage-textures- 読み書き可能なコンピュートテクスチャwebgpu-workgroup-memory- 共有メモリ(10~100 倍高速)webgpu-indirect-draws- GPU 駆動のレンダリング
12. 読み込みとアセット(中程度)
loading-draco-compression- 大きなメッシュには Draco を使うloading-gltf-preferred- glTF 形式を使うgltf-loading-optimization- DRACO/Meshopt/KTX2 を使ったローダーの完全なセットアップloading-progress-feedback- 読み込みの進行状況を表示するloading-async-await- 読み込みに async/await を使うloading-lazy- 重要度の低いアセットを遅延読み込みするloading-cache-assets- キャッシュを有効にするloading-dispose-unused- 未使用のアセットをアンロードする
13. Core Web Vitals(中~高)
core-web-vitals- 3D 向けの LCP、FID、CLS の最適化vitals-lazy-load- IntersectionObserver を使って、スクロールせずに見える範囲より下の 3D を遅延読み込みするvitals-code-split- Three.js モジュールを動的にインポートするvitals-preload- link タグを使って重要なアセットをプリロードするvitals-progressive-loading- 低解像度から高解像度へ段階的に読み込むvitals-placeholders- 読み込み中にプレースホルダーのジオメトリを表示するvitals-web-workers- 負荷の高い処理をワーカーに移すvitals-streaming- 大きなシーンをチャンク単位でストリーミングする
14. カメラとコントロール(低~中)
camera-near-far- near/far クリッピング面を適切な範囲に設定するcamera-fov- 適切な FOV を選ぶcamera-controls-damping- 滑らかな操作のためにダンピングを使うcamera-resize-handler- リサイズを適切に処理するcamera-orbit-limits- オービットコントロールの制限を設定する
15. アニメーション(中程度)
animation-system- AnimationMixer、ブレンディング、モーフターゲット、スケルタルアニメーション
16. 物理演算(中程度)
physics-integration- Rapier、Cannon-es の統合パターンphysics-compute-shaders- コンピュートシェーダーを使った GPU 物理演算
17. WebXR(中程度)
webxr-setup- VR/AR ボタン、コントローラー、ヒットテスト
18. オーディオ(低~中)
audio-spatial- PositionalAudio、HRTF、空間サウンド
19. ポストプロセッシング(中程度)
postprocessing-optimization- pmndrs/postprocessing ガイドpostpro-renderer-config- ポストプロセッシング用に AA、ステンシル、深度を無効にするpostpro-merge-effects- エフェクトを 1 回のパスにまとめるpostpro-selective-bloom- パフォーマンス向上のための選択的ブルームpostpro-resolution-scaling- 解像度を半分にして FPS を 2 倍にするpostpro-webgpu-native- TSL ベースの WebGPU 向けポストプロセッシング
20. 最適化(高)
mobile-optimization- モバイル固有の最適化とチェックリストraycasting-optimization- BVH、レイヤー、GPU ピッキング
21. 本番環境(高)
error-handling-recovery- WebGL コンテキストの喪失と復旧migration-checklist- バージョンごとの破壊的変更
22. デバッグと開発ツール(低)
debug-devtools- 包括的なデバッグツールキットdebug-stats-gl- WebGL/WebGPU のモニタリング用 stats-gldebug-lil-gui- 実行中のパラメーター調整用 lil-guidebug-spector- WebGL のフレームキャプチャ用 Spector.jsdebug-renderer-info- 描画コールとメモリのモニタリングdebug-three-mesh-bvh- BVH による高速レイキャスティングdebug-context-lost- WebGL コンテキストの喪失への対処debug-animation-loop-profiling- レンダーループの各セクションのプロファイリングdebug-conditional- 本番環境でデバッグコードを削除
使用方法
詳細な説明とコード例については、個々のルールファイルを参照してください。
rules/setup-use-import-maps.md
rules/memory-dispose-geometry.md
rules/tsl-complete-reference.md
rules/mobile-optimization.md
各ルールファイルには、以下が含まれています。
- 重要な理由についての簡単な説明
- 説明付きの BAD コード例
- 説明付きの GOOD コード例
- 追加の背景情報と参考資料
主なパターン
最新のインポートマップ
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/",
"three/tsl": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.tsl.js"
}
}
</script>
適切な破棄
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 の基本的な使い方
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));
モバイルの検出
const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, isMobile ? 1.5 : 2));
コメント
Markdown 対応