# react-three-fiber > React Three Fiber and Drei patterns for 3D web applications. Use when implementing 3D viewers, loading GLB/GLTF models, configuring orbit controls, handling WebGL, or optimizing 3D performance. Triggers on R3F, Three.js, Canvas, useFrame, useLoader, OrbitControls, GLTFLoader. - Author: Fernando Velasco - Repository: fervelgo/laaa-ram - Version: 20260209000005 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-09 - Source: https://github.com/fervelgo/laaa-ram - Web: https://mule.run/skillshub/@@fervelgo/laaa-ram~react-three-fiber:20260209000005 --- --- name: react-three-fiber description: React Three Fiber and Drei patterns for 3D web applications. Use when implementing 3D viewers, loading GLB/GLTF models, configuring orbit controls, handling WebGL, or optimizing 3D performance. Triggers on R3F, Three.js, Canvas, useFrame, useLoader, OrbitControls, GLTFLoader. allowed-tools: Read, Grep, Glob, Edit, Write --- # React Three Fiber Development ## Core Patterns ### Basic Canvas Setup ```tsx 'use client' import { Canvas } from '@react-three/fiber' import { OrbitControls, Environment, useProgress, Html } from '@react-three/drei' import { Suspense } from 'react' function Loader() { const { progress } = useProgress() return {progress.toFixed(0)}% loaded } export function ObjectViewer({ modelUrl }: { modelUrl: string }) { return ( }> ) } ``` ### Loading GLB Models ```tsx import { useGLTF } from '@react-three/drei' function Model({ url }: { url: string }) { const { scene } = useGLTF(url) return } // Preload for faster loading useGLTF.preload('/models/preview/object.glb') ``` ### Progressive Loading (Preview -> Full) ```tsx import { useState, useEffect } from 'react' import { useGLTF } from '@react-three/drei' function ProgressiveModel({ previewUrl, fullUrl }: Props) { const [useFullModel, setUseFullModel] = useState(false) const preview = useGLTF(previewUrl) useEffect(() => { // Preload full model in background useGLTF.preload(fullUrl) const timer = setTimeout(() => setUseFullModel(true), 100) return () => clearTimeout(timer) }, [fullUrl]) const full = useGLTF(fullUrl, true) // true = don't block return } ``` ### Mobile Touch Controls ```tsx ``` ### Auto-Rotate Toggle ```tsx function Controls({ autoRotate }: { autoRotate: boolean }) { const controlsRef = useRef(null) return ( ) } ``` ### Reset Camera Position ```tsx import { useThree } from '@react-three/fiber' function ResetButton() { const { camera } = useThree() const defaultPosition = new Vector3(0, 0, 5) const reset = () => { camera.position.copy(defaultPosition) camera.lookAt(0, 0, 0) } return } ``` ## Performance Optimization ### Frame Rate Management ```tsx import { useFrame } from '@react-three/fiber' function Model() { const ref = useRef(null) // Only update when needed useFrame((state, delta) => { if (ref.current && autoRotate) { ref.current.rotation.y += delta * 0.5 } }) return ... } ``` ### Dispose Resources ```tsx useEffect(() => { return () => { // Clean up on unmount scene.traverse((child) => { if (child instanceof THREE.Mesh) { child.geometry.dispose() if (child.material instanceof THREE.Material) { child.material.dispose() } } }) } }, [scene]) ``` ### WebGL Fallback ```tsx function Viewer({ modelUrl, fallbackImage }: Props) { const [webglSupported, setWebglSupported] = useState(true) useEffect(() => { try { const canvas = document.createElement('canvas') const gl = canvas.getContext('webgl') || canvas.getContext('webgl2') setWebglSupported(!!gl) } catch { setWebglSupported(false) } }, []) if (!webglSupported) { return (
3D view unavailable

WebGL is not supported in your browser

) } return ... } ``` ## Common Issues | Issue | Solution | |-------|----------| | Model too dark | Add `` | | Controls not working | Ensure Canvas has size (height/width) | | Model not centered | Use `
` from Drei | | Poor mobile performance | Reduce `dpr`, use simpler models | | Memory leaks | Dispose geometries and materials on unmount |