0
0
ReactHow-ToBeginner · 3 min read

How to Use React Profiler for Performance Monitoring

Use the Profiler component from React to wrap parts of your UI and provide an onRender callback that logs render timings. This helps you measure how often and how long components render, aiding performance optimization.
📐

Syntax

The Profiler component wraps React components you want to measure. It requires two props:

  • id: a unique string to identify the profiler instance.
  • onRender: a callback function called after each render with timing details.

Inside Profiler, place the components you want to track.

jsx
import React, { Profiler } from 'react';

function onRenderCallback(
  id, // the id prop of the Profiler
  phase, // either "mount" or "update"
  actualDuration, // time spent rendering the committed update
  baseDuration, // estimated time to render the entire subtree without memoization
  startTime, // when React began rendering this update
  commitTime, // when React committed this update
  interactions // the Set of interactions belonging to this update
) {
  console.log(`Profiler [${id}] ${phase} phase: ${actualDuration}ms`);
}

function App() {
  return (
    <Profiler id="MyComponent" onRender={onRenderCallback}>
      <MyComponent />
    </Profiler>
  );
}
💻

Example

This example shows a simple counter component wrapped in Profiler. The onRender callback logs how long each render takes, helping you see performance in the browser console.

jsx
import React, { useState, Profiler } from 'react';

function onRenderCallback(id, phase, actualDuration) {
  console.log(`Profiler [${id}] ${phase} phase: ${actualDuration.toFixed(2)}ms`);
}

function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default function App() {
  return (
    <Profiler id="Counter" onRender={onRenderCallback}>
      <Counter />
    </Profiler>
  );
}
Output
Profiler [Counter] mount phase: 1.23ms Profiler [Counter] update phase: 0.45ms
⚠️

Common Pitfalls

  • Not providing a unique id for each Profiler instance can make logs confusing.
  • Ignoring the phase parameter can lead to mixing mount and update timings.
  • Using Profiler on very large trees without memoization can add overhead.
  • Forgetting to check the browser console where the timing logs appear.
jsx
/* Wrong: Missing unique id and ignoring phase */
<Profiler onRender={(...args) => console.log(args)}>
  <MyComponent />
</Profiler>

/* Right: Unique id and clear onRender callback */
<Profiler id="MyComponent" onRender={(id, phase, actualDuration) => {
  console.log(`${id} rendered during ${phase} in ${actualDuration}ms`);
}}>
  <MyComponent />
</Profiler>
📊

Quick Reference

React Profiler Cheat Sheet:

PropDescription
idUnique string to identify the Profiler instance
onRenderCallback function called after each render with timing info
phase"mount" or "update" indicating render type
actualDurationTime spent rendering the update in milliseconds
baseDurationEstimated time to render subtree without memoization

Key Takeaways

Wrap components with Profiler and provide a unique id and onRender callback to measure render times.
Use the onRender callback to log or analyze render durations for performance insights.
Check the browser console to see profiler logs after component renders.
Avoid wrapping very large component trees without memoization to reduce profiling overhead.
Distinguish between "mount" and "update" phases to understand initial and subsequent renders.