Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 60x 60x 60x 30x 60x 30x 60x 60x 60x 60x 30x 30x 60x | /**
* React hook for Three.js performance monitoring
*
* Integrates PerformanceMonitor with useFrame for real-time FPS tracking
*/
import { useFrame, useThree } from '@react-three/fiber';
import { useEffect, useMemo, useRef, useState } from 'react';
import { PerformanceMonitor, PerformanceMetrics, PerformanceThresholds } from './PerformanceMonitor';
export interface UsePerformanceMonitorOptions {
readonly enabled?: boolean;
readonly thresholds?: Partial<PerformanceThresholds>;
readonly updateInterval?: number; // Update interval in ms for React state
}
export interface PerformanceMonitorState {
readonly metrics: PerformanceMetrics;
readonly isGood: boolean;
readonly warnings: readonly string[];
}
/**
* Hook for monitoring Three.js performance in real-time
*
* @param options Configuration options
* @returns Current performance state
*
* @example
* ```tsx
* function CombatScene() {
* const { metrics, isGood, warnings } = usePerformanceMonitor({
* enabled: import.meta.env.DEV,
* thresholds: { minAcceptableFps: 55 }
* });
*
* return (
* <>
* {import.meta.env.DEV && (
* <Html position={[0, 5, 0]}>
* <div>FPS: {metrics.fps.toFixed(1)}</div>
* </Html>
* )}
* {/* 3D content */}
* </>
* );
* }
* ```
*/
export function usePerformanceMonitor(
options: UsePerformanceMonitorOptions = {}
): PerformanceMonitorState {
const { enabled = true, thresholds, updateInterval = 1000 } = options;
const gl = useThree((state) => state.gl);
// Memoize thresholds to prevent unnecessary monitor recreation
const stableThresholds = useMemo(
() => thresholds,
[thresholds]
);
const monitor = useMemo(
() => new PerformanceMonitor(stableThresholds),
[stableThresholds]
);
const [state, setState] = useState<PerformanceMonitorState>(() => ({
metrics: monitor.getMetrics(gl),
isGood: monitor.isPerformanceGood(),
warnings: monitor.getWarnings(),
}));
const lastUpdateRef = useRef(0);
// Update performance monitor every frame
useFrame(() => {
if (!enabled) return;
monitor.update(gl);
// Update React state at specified interval
const now = performance.now();
if (now - lastUpdateRef.current >= updateInterval) {
lastUpdateRef.current = now;
setState({
metrics: monitor.getMetrics(gl),
isGood: monitor.isPerformanceGood(),
warnings: monitor.getWarnings(),
});
}
});
// Reset monitor on unmount
useEffect(() => {
return () => {
monitor.reset();
};
}, [monitor]);
return state;
}
export default usePerformanceMonitor;
|