Back to React
React
medium
mid

How do you distinguish between React side and browser side rendering bottlenecks?

React DevTools Profiler measures component render time and shows what re-rendered and why. Chrome Performance panel shows main-thread tasks including style, layout, paint, composite — browser work. If Profiler shows fast renders but the user sees jank, the browser's layout/paint is the culprit. If Profiler shows slow renders, optimize React (memo, lists, context). Pair the two tools.

4 min read·~8 min to think through

The split

CostToolSymptom
React render time (component functions, reconciliation)React DevTools ProfilerLong bars in flamegraph
Style recalc, layout, paint, composite (browser)Chrome Performance panelStyle/Layout/Paint rows
Network / image decode / GPUChrome Performance + LighthouseSpecific resource phases
Main-thread JS that isn't React (analytics, parsers)Chrome PerformanceLong Tasks

Workflow

  1. Reproduce the interaction with CPU throttle.
  2. Record in React DevTools Profiler first — does any component render > 16ms?
  • If yes → React side. Look at "Why did this render" + commit duration.
  • If no → browser side or non-React.
  1. Record in Chrome Performance for the same interaction.
  • Look at the main-thread row.
  • Long tasks > 50ms flagged.
  • The bottom rows (style, layout, paint) show browser work.
  1. Correlate: React commit at time T. Right after it, big layout/paint? That's the DOM mutation triggering browser work.

Symptoms of each side

SymptomSide
Same data, slow updateProbably React (re-render fan-out)
Adding nodes, then scroll jankBrowser (layout / paint cost)
Animation stutterBrowser (composite / GPU)
Long input delayEither; check Profiler first

Common React-side fixes

  • Memo + stable refs for the actual hot subtree.
  • Split context fan-out.
  • useDeferredValue or startTransition for non-urgent.
  • Virtualize long lists.

Common browser-side fixes

  • Composite-only animations (transform/opacity).
  • contain: layout style paint on isolated subtrees.
  • Avoid layout thrash (batch reads/writes).
  • Reduce DOM node count (virtualize).
  • Optimize images (size, format).
  • Reduce paint area (smaller box-shadows, simpler filters).

A practical example

ts
User drags a sidebar.
Profiler: 0.5ms commit (cheap).
Performance: massive Layout bar (20ms) after each commit.

React isn't slow; the browser is laying out a deep tree on every frame. Add will-change: width or restructure CSS so only the sidebar element relayouts, not its content.

Pitfall: profiler overhead in dev

React's Profiler measurements aren't representative of production. Always build in NODE_ENV=production for accurate timing. The profiler still helps in dev for relative costs and re-render reasons.

Interview framing

"Two tools: React DevTools Profiler for render time + 'why did this render' (the React side), and Chrome Performance panel for the browser side (style recalc, layout, paint, composite). If Profiler shows fast commits but the UI feels janky, browser work is the bottleneck — usually layout cost from big DOM mutations, paint area, or non-composite animations. If Profiler shows long renders or unexpected re-renders, optimize React: memo + stable refs, split context, virtualize. Pair the tools — they tell different stories. Always profile production builds for accurate numbers."

Follow-up questions

  • What's the Performance panel's bottom-up view useful for?
  • How do you distinguish a layout cost from a paint cost?
  • When would you use the Performance panel over the Profiler?

Common mistakes

  • Optimizing React when the browser is the bottleneck.
  • Profiling in dev and trusting numbers.
  • Ignoring layout/paint rows in Performance.

Performance considerations

  • The whole question is performance categorization.

Edge cases

  • Sync layout from JS reads forcing reflow.
  • Heavy filters / shadows causing paint storms.
  • GPU memory limits on mobile.

Real-world examples

  • Long-list scroll perf, drag interactions, animation stutter case studies.

Senior engineer discussion

Seniors switch between the two tools fluently and identify when CSS architecture (not React) is the real issue.

Related questions