mcpField
R
r3f-best-practices

r3f-best-practices

github.com/emalorenzo開発651.5k 回インストール39 週間前に更新
リポジトリ

r3f-best-practices について

React Three Fiber開発者向けの実践ガイドで、パフォーマンス、アニメーション、コンポーネント、Poimandresエコシステムのツールを扱います。影響度順にルールを整理し、個別のルールファイルと例を参照できます。

主な機能

  1. 0170以上の実践ルール
  2. 02影響度に基づく分類
  3. 03パフォーマンスと再レンダリングの指針
  4. 04アニメーション、状態、操作を網羅
  5. 05ルールファイルとコード例

活用シーン

  1. 01React Three Fiberシーンの性能改善
  2. 02useFrameアニメーションと状態管理の実装
  3. 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.md
drei-use-gltf.md
frame-delta-time.md
loading-suspense.md
perf-never-set-state-in-useframe.md
perf-r3f-perf.md
perf-visibility-toggle.md
perf-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パフォーマンスと再レンダーCRITICALperf-
2useFrame とアニメーションCRITICALframe-
3コンポーネントのパターンHIGHcomponent-
4Canvas とセットアップHIGHcanvas-
5Drei ヘルパーMEDIUM-HIGHdrei-
6読み込みと SuspenseMEDIUM-HIGHloading-
7状態管理MEDIUMstate-
8イベントとインタラクションMEDIUMevents-
9ポストプロセッシングMEDIUMpostpro-
10物理演算(Rapier)LOW-MEDIUMphysics-
11Leva(デバッグ GUI)LOWleva-

クイックリファレンス

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 - プリロード付きの useGLTF
  • drei-use-texture - テクスチャ読み込み用の useTexture
  • drei-environment - リアルなライティングのための Environment
  • drei-orbit-controls - Drei の OrbitControls
  • drei-html - DOM オーバーレイ用の Html
  • drei-text - 3D テキスト用の Text
  • drei-instances - 最適化されたインスタンシング用の Instances
  • drei-use-helper - デバッグ可視化用の useHelper
  • drei-bounds - カメラをフィットさせる Bounds
  • drei-center - オブジェクトを中央に配置する Center
  • drei-float - 浮遊アニメーション用の Float
6. 読み込みと Suspense (MEDIUM-HIGH)
  • loading-suspense - 非同期コンポーネントを Suspense でラップする
  • loading-preload - useGLTF.preload でアセットをプリロードする
  • loading-use-progress - 読み込み UI 用の useProgress
  • loading-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 - 最適化されたグロー用の SelectiveBloom
  • postpro-custom-shader - カスタムエフェクトを作成する
  • postpro-performance - ポストプロセッシングを最適化する
10. 物理演算 Rapier (LOW-MEDIUM)
  • physics-setup - 基本的な Rapier のセットアップ
  • physics-body-types - dynamic、fixed、kinematic
  • physics-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} />

コメント