React Native Performance Profiling
React Native Performance Profiling
~14 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
Just as in "React for Professionals": MEASURE first, then optimize. React Native ships its own, platform-specific tools for this, going beyond plain React DevTools – they also show what's happening on the NATIVE and shadow threads (see the "React Native Reference" series, the "Threads" topic, for the basics of this three-thread architecture).
The built-in performance monitor
Open the developer menu (shake the device, or Cmd+D/Cmd+M in the simulator/emulator) and select "Show Perf Monitor". A small overlay shows the JS frame rate and the UI frame rate live, SEPARATELY – EXACTLY this separation makes visible what "React for Professionals" chapter 35 (Fiber, render vs. commit phase) explained conceptually: the JS thread can be slow while native animations still run smoothly at 60fps on the UI thread (and vice versa).
React DevTools Profiler – identical to React for Professionals
The React DevTools profiler from "React for Professionals" chapter 30 works IDENTICALLY in React Native – the same flame chart view, the same "why did this render" feature. Connect the app via npx react-devtools in a separate terminal window (instead of the browser extension, since React Native has no browser).
npx react-devtoolsThen start the app normally (npx expo start) – the standalone DevTools app connects automatically and shows the same "⚛️ Profiler" tab as in the browser.
Flipper and the new "React Native DevTools"
Flipper was long the standard debugging tool for React Native (network inspector, layout inspector, log viewer, all in ONE desktop app) – since React Native 0.73, it's increasingly being replaced by the INTEGRATED React Native DevTools (reachable directly from the developer menu, "Open DevTools"), based on the same Chrome DevTools protocol as web debugging. For new projects, the integrated route is recommended; Flipper remains relevant for older projects.
In practice: reusing the RenderCounter from "React for Professionals"
The pattern from "React for Professionals" chapter 27 works unchanged in React Native – useRef for counting renders without triggering any of its own:
import { useRef } from 'react';
import { Text } from 'react-native';
function RenderCounter({ label }) {
const renderCount = useRef(0);
renderCount.current += 1;
return (
<Text style={{ fontSize: 10, opacity: 0.5 }}>
???? {label}: {renderCount.current}×
</Text>
);
}
export default RenderCounter;Add <RenderCounter label="ProductCard" /> to ProductCard as a test and favorite a product in ProductListScreen: you'll see that ALL visible ProductCard instances re-render, not just the one you tapped – useSelector returns a NEW favoriteSkus array on EVERY toggleFavorite action (chapter 3), which makes favoriteSkus.includes(item.sku) get re-evaluated for EVERY card AND (without React.memo, see next chapter) every card re-renders, even if its OWN isFavorite result didn't change at all.
Bonus: inspecting the JavaScript bundle
npx expo export produces a production-like export including the JS bundle – useful for checking how large the JavaScript bundle actually is BEFORE a real store release (see "React for Professionals" chapter 46 for the bundle-analysis technique with rollup-plugin-visualizer; for Expo/Metro there's the analogous tool source-map-explorer).
Tipp: Rule of thumb: before applying ANY optimization from the next three chapters (FlatList, Hermes, images), FIRST measure with the perf monitor AND the React DevTools profiler to see WHICH thread/WHICH component is actually the problem. A stuttering FlatList needs a different fix than a slow JS computation – both "feel slow", but the causes AND solutions differ fundamentally.