r3f-best-practices について
React Three Fiber開発者向けの実践ガイドで、パフォーマンス、アニメーション、コンポーネント、Poimandresエコシステムのツールを扱います。影響度順にルールを整理し、個別のルールファイルと例を参照できます。
主な機能
- 0170以上の実践ルール
- 02影響度に基づく分類
- 03パフォーマンスと再レンダリングの指針
- 04アニメーション、状態、操作を網羅
- 05ルールファイルとコード例
活用シーン
- 01React Three Fiberシーンの性能改善
- 02useFrameアニメーションと状態管理の実装
- 03Dreiによる3Dアセットの読み込みと処理
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ emalorenzo/ three-agent-skills --skill r3f-best-practicesインストール後、Claude Code で/r3f-best-practicesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
rules/_sections.mddrei-use-gltf.mdframe-delta-time.mdloading-suspense.mdperf-never-set-state-in-useframe.mdperf-r3f-perf.mdperf-visibility-toggle.mdperf-zustand-selectors.md詳細
React Three Fiber のベストプラクティス
React Three Fiber と Poimandres エコシステムの包括的なガイドです。影響度に基づいて優先順位を付けた、12 カテゴリにわたる 70 以上のルールを掲載しています。
情報源とクレジット
Utsubo による 100 Three.js Tips からの追加のヒントです。
適用する場面
以下の場合に、このガイドラインを参照してください。
- 新しい R3F コンポーネントを作成するとき
- R3F のパフォーマンスを最適化するとき(再レンダーが最大の問題です)
- Drei ヘルパーを正しく使用するとき
- Zustand で状態を管理するとき
- ポストプロセッシングや物理演算を実装するとき
対象エコシステム
- @react-three/fiber - Three.js 用の React レンダラー
- @react-three/drei - 便利なヘルパーと抽象化機能
- @react-three/postprocessing - ポストプロセッシングエフェクト
- @react-three/rapier - 物理エンジン
- zustand - 状態管理
- leva - デバッグ GUI
優先度別のルールカテゴリ
| 優先度 | カテゴリ | 影響度 | プレフィックス |
|---|---|---|---|
| 1 | パフォーマンスと再レンダー | CRITICAL | perf- |
| 2 | useFrame とアニメーション | CRITICAL | frame- |
| 3 | コンポーネントのパターン | HIGH | component- |
| 4 | Canvas とセットアップ | HIGH | canvas- |
| 5 | Drei ヘルパー | MEDIUM-HIGH | drei- |
| 6 | 読み込みと Suspense | MEDIUM-HIGH | loading- |
| 7 | 状態管理 | MEDIUM | state- |
| 8 | イベントとインタラクション | MEDIUM | events- |
| 9 | ポストプロセッシング | MEDIUM | postpro- |
| 10 | 物理演算(Rapier) | LOW-MEDIUM | physics- |
| 11 | Leva(デバッグ GUI) | LOW | leva- |
クイックリファレンス
1. パフォーマンスと再レンダー(CRITICAL)
perf-never-set-state-in-useframe- useFrame 内で setState を絶対に呼び出さないperf-isolate-state- React の状態が必要なコンポーネントを分離するperf-zustand-selectors- ストア全体ではなく、Zustand セレクターを使用するperf-transient-subscriptions- 連続的に変化する値には一時的なサブスクリプションを使用するperf-memo-components- コストの高いコンポーネントをメモ化するperf-keys-for-lists- 動的リストには安定したキーを使用するperf-avoid-inline-objects- JSX 内でオブジェクトや配列を生成しないperf-dispose-auto- R3F の自動破棄の動作を理解するperf-visibility-toggle- 再マウントする代わりに表示状態を切り替えるperf-r3f-perf- パフォーマンスの監視に r3f-perf を使用する
2. useFrame とアニメーション(CRITICAL)
frame-priority- 実行順序には優先度を使用するframe-delta-time- アニメーションでは常に delta を使用するframe-conditional-subscription- 不要なときは useFrame を無効にするframe-destructure-state- 必要な値だけを分割代入するframe-render-on-demand- オンデマンドレンダリングには invalidate() を使用するframe-avoid-heavy-computation- 負荷の高い処理は useFrame の外に移す
3. コンポーネントのパターン(HIGH)
component-jsx-elements- Three.js オブジェクトには JSX を使用するcomponent-attach-prop- 標準ではないプロパティには attach を使用するcomponent-primitive- 既存のオブジェクトには primitive を使用するcomponent-extend- カスタムクラスには extend() を使用するcomponent-forwardref- 再利用可能なコンポーネントには forwardRef を使用するcomponent-dispose-null- 共有リソースには dispose={null} を設定する
4. Canvas とセットアップ(HIGH)
canvas-size-container- Canvas を親コンテナーいっぱいに広げるcanvas-camera-default- prop を使ってカメラを設定するcanvas-gl-config- WebGL コンテキストを設定するcanvas-shadows- Canvas レベルでシャドウを有効にするcanvas-frameloop- 適切な frameloop モードを選択するcanvas-events- イベント処理を設定するcanvas-linear-flat- 正しい色を表示するには linear/flat を使用する
5. Drei ヘルパー (MEDIUM-HIGH)
drei-use-gltf- プリロード付きの useGLTFdrei-use-texture- テクスチャ読み込み用の useTexturedrei-environment- リアルなライティングのための Environmentdrei-orbit-controls- Drei の OrbitControlsdrei-html- DOM オーバーレイ用の Htmldrei-text- 3D テキスト用の Textdrei-instances- 最適化されたインスタンシング用の Instancesdrei-use-helper- デバッグ可視化用の useHelperdrei-bounds- カメラをフィットさせる Boundsdrei-center- オブジェクトを中央に配置する Centerdrei-float- 浮遊アニメーション用の Float
6. 読み込みと Suspense (MEDIUM-HIGH)
loading-suspense- 非同期コンポーネントを Suspense でラップするloading-preload- useGLTF.preload でアセットをプリロードするloading-use-progress- 読み込み UI 用の useProgressloading-lazy-components- 重いコンポーネントを遅延読み込みするloading-error-boundary- 読み込みエラーを処理する
7. 状態管理 (MEDIUM)
state-zustand-store- 責務を絞った Zustand ストアを作成するstate-avoid-objects-in-store- Three.js オブジェクトの扱いに注意するstate-subscribeWithSelector- きめ細かいサブスクリプションstate-persist- 必要に応じて状態を永続化するstate-separate-concerns- 関心事ごとにストアを分離する
8. イベントとインタラクション (MEDIUM)
events-pointer-events- メッシュでポインターイベントを使用するevents-stop-propagation- イベントのバブリングを防ぐevents-cursor-pointer- ホバー時にカーソルを変更するevents-raycast-filter- レイキャストをフィルタリングするevents-event-data- イベントデータの構造を理解する
9. ポストプロセッシング (MEDIUM)
postpro-effect-composer- EffectComposer を使用するpostpro-common-effects- 一般的なエフェクトのリファレンスpostpro-selective-bloom- 最適化されたグロー用の SelectiveBloompostpro-custom-shader- カスタムエフェクトを作成するpostpro-performance- ポストプロセッシングを最適化する
10. 物理演算 Rapier (LOW-MEDIUM)
physics-setup- 基本的な Rapier のセットアップphysics-body-types- dynamic、fixed、kinematicphysics-colliders- 適切なコライダーを選択するphysics-events- 衝突イベントを処理するphysics-api-ref- 物理演算 API に ref を使用するphysics-performance- 物理演算を最適化する
11. Leva (LOW)
leva-basic- 基本的な Leva の使い方leva-folders- フォルダーで整理するleva-conditional- 本番環境では非表示にする
使い方
詳細な説明とコード例については、個々のルールファイルをお読みください:
rules/perf-never-set-state-in-useframe.md
rules/drei-use-gltf.md
rules/state-zustand-selectors.md
完全なコンパイル済みドキュメント
すべてのルールを展開した完全なガイド: ../R3F_BEST_PRACTICES.md
重要なパターン
useFrame 内で絶対に setState しない
// BAD - 60 re-renders per second!
function BadComponent() {
const [position, setPosition] = useState(0);
useFrame(() => {
setPosition(p => p + 0.01); // NEVER DO THIS
});
return <mesh position-x={position} />;
}
// GOOD - Mutate refs directly
function GoodComponent() {
const meshRef = useRef();
useFrame(() => {
meshRef.current.position.x += 0.01;
});
return <mesh ref={meshRef} />;
}
Zustand セレクター
// BAD - Re-renders on ANY store change
const store = useGameStore();
// GOOD - Only re-renders when playerX changes
const playerX = useGameStore(state => state.playerX);
// BETTER - No re-renders, direct mutation
useFrame(() => {
const { value } = useStore.getState();
ref.current.position.x = value;
});
Drei useGLTF
import { useGLTF } from '@react-three/drei';
function Model() {
const { scene } = useGLTF('/model.glb');
return <primitive object={scene} />;
}
// Preload for instant loading
useGLTF.preload('/model.glb');
Suspense による読み込み
function App() {
return (
<Canvas>
<Suspense fallback={<Loader />}>
<Model />
</Suspense>
</Canvas>
);
}
r3f-perf によるモニタリング
import { Perf } from 'r3f-perf';
function App() {
return (
<Canvas>
<Perf position="top-left" />
<Scene />
</Canvas>
);
}
可視性の切り替え (再マウントではない)
// BAD: Remounting destroys and recreates
{showModel && <Model />}
// GOOD: Toggle visibility, keeps instance alive
<Model visible={showModel} />
コメント
Markdown 対応