r3f-best-practices by emalorenzo/three-agent-skills
npx skills add https://github.com/emalorenzo/three-agent-skills --skill r3f-best-practicesReact Three Fiber 及 Poimandres 生态系统的综合指南。包含 12 个类别下的 70 多条规则,按影响优先级排序。
额外技巧来自 Utsubo 的 100 Three.js 技巧
在以下情况下参考这些指南:
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 1 |
| 性能与重新渲染 |
| 关键 |
perf- |
| 2 | useFrame 与动画 | 关键 | frame- |
| 3 | 组件模式 | 高 | component- |
| 4 | Canvas 与设置 | 高 | canvas- |
| 5 | Drei 辅助工具 | 中高 | drei- |
| 6 | 加载与 Suspense | 中高 | loading- |
| 7 | 状态管理 | 中 | state- |
| 8 | 事件与交互 | 中 | events- |
| 9 | 后期处理 | 中 | postpro- |
| 10 | 物理 (Rapier) | 低中 | physics- |
| 11 | Leva (调试 GUI) | 低 | leva- |
perf-never-set-state-in-useframe - 切勿在 useFrame 中调用 setStateperf-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 进行性能监控frame-priority - 使用优先级控制执行顺序frame-delta-time - 始终使用 delta 进行动画frame-conditional-subscription - 不需要时禁用 useFrameframe-destructure-state - 仅解构所需内容frame-render-on-demand - 使用 invalidate() 进行按需渲染frame-avoid-heavy-computation - 将繁重工作移到 useFrame 外部component-jsx-elements - 对 Three.js 对象使用 JSXcomponent-attach-prop - 对非标准属性使用 attachcomponent-primitive - 对现有对象使用 primitivecomponent-extend - 对自定义类使用 extend()component-forwardref - 对可复用组件使用 forwardRefcomponent-dispose-null - 对共享资源设置 dispose={null}canvas-size-container - Canvas 填充父容器canvas-camera-default - 通过属性配置相机canvas-gl-config - 配置 WebGL 上下文canvas-shadows - 在 Canvas 层级启用阴影canvas-frameloop - 选择合适的帧循环模式canvas-events - 配置事件处理canvas-linear-flat - 使用 linear/flat 以获得正确的颜色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 - 用于浮动动画的 Floatloading-suspense - 将异步组件包裹在 Suspense 中loading-preload - 使用 useGLTF.preload 预加载资源loading-use-progress - 用于加载 UI 的 useProgressloading-lazy-components - 懒加载重型组件loading-error-boundary - 处理加载错误state-zustand-store - 创建专注的 Zustand 存储state-avoid-objects-in-store - 谨慎处理 Three.js 对象state-subscribeWithSelector - 细粒度订阅state-persist - 需要时持久化状态state-separate-concerns - 按关注点分离存储events-pointer-events - 在网格上使用指针事件events-stop-propagation - 阻止事件冒泡events-cursor-pointer - 悬停时更改光标events-raycast-filter - 过滤光线投射events-event-data - 理解事件数据结构postpro-effect-composer - 使用 EffectComposerpostpro-common-effects - 常见效果参考postpro-selective-bloom - 用于优化辉光的 SelectiveBloompostpro-custom-shader - 创建自定义效果postpro-performance - 优化后期处理physics-setup - 基本 Rapier 设置physics-body-types - dynamic, fixed, kinematicphysics-colliders - 选择合适的碰撞体physics-events - 处理碰撞事件physics-api-ref - 使用 ref 访问物理 APIphysics-performance - 优化物理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
// 错误 - 每秒 60 次重新渲染!
function BadComponent() {
const [position, setPosition] = useState(0);
useFrame(() => {
setPosition(p => p + 0.01); // 切勿这样做
});
return <mesh position-x={position} />;
}
// 正确 - 直接修改 refs
function GoodComponent() {
const meshRef = useRef();
useFrame(() => {
meshRef.current.position.x += 0.01;
});
return <mesh ref={meshRef} />;
}
// 错误 - 存储的任何更改都会导致重新渲染
const store = useGameStore();
// 正确 - 仅当 playerX 更改时重新渲染
const playerX = useGameStore(state => state.playerX);
// 更好 - 无重新渲染,直接修改
useFrame(() => {
const { value } = useStore.getState();
ref.current.position.x = value;
});
import { useGLTF } from '@react-three/drei';
function Model() {
const { scene } = useGLTF('/model.glb');
return <primitive object={scene} />;
}
// 预加载以实现即时加载
useGLTF.preload('/model.glb');
function App() {
return (
<Canvas>
<Suspense fallback={<Loader />}>
<Model />
</Suspense>
</Canvas>
);
}
import { Perf } from 'r3f-perf';
function App() {
return (
<Canvas>
<Perf position="top-left" />
<Scene />
</Canvas>
);
}
// 错误:重新挂载会销毁并重新创建
{showModel && <Model />}
// 正确:切换可见性,保持实例存活
<Model visible={showModel} />
每周安装量
342
仓库
GitHub 星标数
14
首次出现
2026年1月19日
安全审计
安装于
opencode257
gemini-cli253
codex243
github-copilot227
cursor219
claude-code208
Comprehensive guide for React Three Fiber and the Poimandres ecosystem. Contains 70+ rules across 12 categories, prioritized by impact.
Additional tips from 100 Three.js Tips by Utsubo
Reference these guidelines when:
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Performance & Re-renders | CRITICAL | perf- |
| 2 | useFrame & Animation | CRITICAL | frame- |
| 3 | Component Patterns | HIGH | component- |
| 4 | Canvas & Setup | HIGH | canvas- |
| 5 | Drei Helpers | MEDIUM-HIGH | drei- |
| 6 | Loading & Suspense |
perf-never-set-state-in-useframe - NEVER call setState in useFrameperf-isolate-state - Isolate components that need React stateperf-zustand-selectors - Use Zustand selectors, not entire storeperf-transient-subscriptions - Use transient subscriptions for continuous valuesperf-memo-components - Memoize expensive componentsperf-keys-for-lists - Use stable keys for dynamic listsperf-avoid-inline-objects - Avoid creating objects/arrays in JSXperf-dispose-auto - Understand R3F auto-dispose behaviorperf-visibility-toggle - Toggle visibility instead of remountingframe-priority - Use priority for execution orderframe-delta-time - Always use delta for animationsframe-conditional-subscription - Disable useFrame when not neededframe-destructure-state - Destructure only what you needframe-render-on-demand - Use invalidate() for on-demand renderingframe-avoid-heavy-computation - Move heavy work outside useFramecomponent-jsx-elements - Use JSX for Three.js objectscomponent-attach-prop - Use attach for non-standard propertiescomponent-primitive - Use primitive for existing objectscomponent-extend - Use extend() for custom classescomponent-forwardref - Use forwardRef for reusable componentscomponent-dispose-null - Set dispose={null} on shared resourcescanvas-size-container - Canvas fills parent containercanvas-camera-default - Configure camera via propcanvas-gl-config - Configure WebGL contextcanvas-shadows - Enable shadows at Canvas levelcanvas-frameloop - Choose appropriate frameloop modecanvas-events - Configure event handlingcanvas-linear-flat - Use linear/flat for correct colorsdrei-use-gltf - useGLTF with preloadingdrei-use-texture - useTexture for texture loadingdrei-environment - Environment for realistic lightingdrei-orbit-controls - OrbitControls from Dreidrei-html - Html for DOM overlaysdrei-text - Text for 3D textdrei-instances - Instances for optimized instancingdrei-use-helper - useHelper for debug visualizationdrei-bounds - Bounds to fit cameraloading-suspense - Wrap async components in Suspenseloading-preload - Preload assets with useGLTF.preloadloading-use-progress - useProgress for loading UIloading-lazy-components - Lazy load heavy componentsloading-error-boundary - Handle loading errorsstate-zustand-store - Create focused Zustand storesstate-avoid-objects-in-store - Be careful with Three.js objectsstate-subscribeWithSelector - Fine-grained subscriptionsstate-persist - Persist state when neededstate-separate-concerns - Separate stores by concernevents-pointer-events - Use pointer events on meshesevents-stop-propagation - Prevent event bubblingevents-cursor-pointer - Change cursor on hoverevents-raycast-filter - Filter raycastingevents-event-data - Understand event data structurepostpro-effect-composer - Use EffectComposerpostpro-common-effects - Common effects referencepostpro-selective-bloom - SelectiveBloom for optimized glowpostpro-custom-shader - Create custom effectspostpro-performance - Optimize post-processingphysics-setup - Basic Rapier setupphysics-body-types - dynamic, fixed, kinematicphysics-colliders - Choose appropriate collidersphysics-events - Handle collision eventsphysics-api-ref - Use ref for physics APIphysics-performance - Optimize physicsleva-basic - Basic Leva usageleva-folders - Organize with foldersleva-conditional - Hide in productionRead individual rule files for detailed explanations and code examples:
rules/perf-never-set-state-in-useframe.md
rules/drei-use-gltf.md
rules/state-zustand-selectors.md
For the complete guide with all rules expanded: ../R3F_BEST_PRACTICES.md
// 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} />;
}
// 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;
});
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');
function App() {
return (
<Canvas>
<Suspense fallback={<Loader />}>
<Model />
</Suspense>
</Canvas>
);
}
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} />
Weekly Installs
342
Repository
GitHub Stars
14
First Seen
Jan 19, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode257
gemini-cli253
codex243
github-copilot227
cursor219
claude-code208
GSAP React 动画库使用指南:useGSAP Hook 与最佳实践
1,700 周安装
| MEDIUM-HIGH |
loading- |
| 7 | State Management | MEDIUM | state- |
| 8 | Events & Interaction | MEDIUM | events- |
| 9 | Post-processing | MEDIUM | postpro- |
| 10 | Physics (Rapier) | LOW-MEDIUM | physics- |
| 11 | Leva (Debug GUI) | LOW | leva- |
perf-r3f-perf - Use r3f-perf for performance monitoringdrei-center - Center to center objectsdrei-float - Float for floating animation