Prompt
Create a PerformanceMonitor component that shows JS-thread FPS by counting requestAnimationFrame callbacks and sampling with setInterval. Update every second.
Solution
The technique is honest and the caveats are the interview. Counting requestAnimationFrame callbacks per second measures the JS thread: if your JS FPS drops, something is blocking the event loop — a heavy render pass, JSON parsing, an accidental O(n²). But React Native runs UI on a separate thread, so JS FPS and UI FPS diverge — a native-driven animation (useNativeDriver, Reanimated worklets) stays at 60 while JS is frozen, and vice versa. Reporting one number as "the FPS" is the junior mistake; know which thread you measured. The in-app Perf Monitor (dev menu) shows both for exactly this reason.
Implementation details that carry the points: the counter lives in a useRef because incrementing it 60 times a second in useState would itself cause 60 renders a second — the monitor becoming the perf problem. The cleanup returns from useEffect and cancels both the interval and the rAF loop; leaking a rAF loop after unmount is a real memory-and-CPU leak.
Also say where this fits: an overlay like this is a dev tool. Production performance is measured as trends — cold start, TTI, slow/frozen frame rates via performance monitoring — not by shipping an FPS counter.
Red flag: measuring in a dev build and quoting the numbers — dev mode disables optimizations and runs dramatically slower; performance claims come from release builds on mid-range hardware.
Say it: "rAF counting measures the JS thread only — UI runs on its own thread in React Native — so I always name which thread dropped frames, and I measure on release builds."