React Native Performance: What I Measure and Fix First

Published: (February 17, 2026 at 04:39 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Cover image for React Native Performance: What I Measure and Fix First

What I Measure

  • Startup time – Time from tap to first meaningful paint (e.g., home screen visible).
    Tools: Flipper, React Native’s built‑in perf tools, or a simple timestamp in native code. Compare before/after changes (new libs, more initial data) to avoid regressions.

  • Frame rate (FPS) – Especially on scroll and animation.
    Tools: React Native’s “Show Perf Monitor” or Flipper (shows JS and UI thread FPS). Drops below 60 FPS (or 120 FPS on capable devices) indicate jank. Note which screen or list causes it.

  • List scroll – Long lists are a common bottleneck.
    Check:

    • Are we using FlatList (or similar)?
    • Are we rendering too many items or heavy components per row?
    • Are we doing work on the JS thread during scroll?
  • Memory – Watch for leaks (memory growing over time) and large allocations.
    Tools: Flipper or Xcode/Android Studio profilers. Leaks often stem from images, caches, or listeners not cleaned up.

  • Bundle size – Large JS bundles slow startup.
    Run npx react-native bundle --dev false and inspect the output size. Look for heavy dependencies that could be lazy‑loaded or replaced.

Baseline per release

Track a small set of numbers per release (e.g., startup time, list FPS on the main feed, memory after 5 minutes). Store them in a document or CI pipeline. When a new feature lands, compare against the baseline so regressions are obvious rather than “it feels slower.”

Fixes I Reach For First

Lists

// Example: enabling getItemLayout for fixed‑height items
const getItemLayout = (data, index) => ({
  length: ITEM_HEIGHT,
  offset: ITEM_HEIGHT * index,
  index,
});
  • Use FlatList (or FlashList for higher throughput).
  • Implement getItemLayout when item height is fixed.
  • Adjust windowSize and maxToRenderPerBatch to limit items in the tree.
  • Memoize list item components to avoid re‑rendering on every scroll tick.
  • Avoid inline functions and object literals in renderItem; pass stable props.

Images

  • Use resizeMode appropriately.
  • Serve correctly sized images from the backend or a CDN that resizes.
  • Consider react-native-fast-image for better caching.
  • Lazy‑load off‑screen images in lists.

Re‑renders

const MemoizedComponent = React.memo(MyComponent);
const stableCallback = useCallback(() => { /* … */ }, []);
const stableValue = useMemo(() => computeExpensiveValue(), []);
  • Detect unnecessary re‑renders with React DevTools Profiler or “Highlight updates.”
  • Lift state so only the needed part re‑renders.
  • Avoid setting state in render or in effects that run too often.

JS thread

  • Move heavy work off the JS thread: use native modules for intensive computation, or batch work with InteractionManager.runAfterInteractions.
  • Avoid large synchronous operations on the main JS thread during startup or scroll.

Startup

  • Reduce initial JS bundle size: lazy‑load screens (React.lazy + code splitting where supported), defer non‑critical imports, and trim dependencies.
  • Enable Hermes if not already; it often improves startup time and memory usage.

Cleanup

  • Unsubscribe from listeners, clear timers, and cancel requests in useEffect cleanup.
  • Remove event listeners and close connections to prevent memory leaks or unnecessary background work.

I fix one area at a time, measure again, and repeat. Small, verified improvements add up; random “optimizations” without measurement often don’t.

Saad Mehmood — Portfolio

0 views
Back to Blog

Related posts

Read more »

Common problems in Windows

Computer is running slowly - Reboot the computer fixes many issues. - If reboot doesn't help, verify sufficient CPU, disk space, and RAM for the OS, hardware,...

Virtualisation with TanStack Virtual

Optimising Performance with Virtualisation in React Optimising performance is a common topic in the React community. Users expect smooth scrolling and quick in...