Skip to main content

useRenderTracking

Track how many times your components render and identify performance issues.

Overview​

useRenderTracking counts component renders and tracks render frequency, helping you identify components that re-render too often and need optimization.

API​

useRenderTracking(componentName: string, options?: RenderTrackingOptions);

Parameters:

  • componentName: Name to identify the component
  • options: Optional configuration
    • logRenders: Log each render to console (default: false)
    • warnThreshold: Warn if renders exceed this number (default: 50)

Basic Example​

import { useRenderTracking } from 'react-dev-debugger';

function MyComponent() {
useRenderTracking('MyComponent');

return <div>Content</div>;
}

Live Playground​

Component Tracking

Parent Component
Component:Parent
Renders:1
Avg Time Between:0ms
Last Render:0ms ago
function Parent() {
  useRenderTracking('Parent', {
    logRenders: true,
    warnThreshold: 10
  });
  
  return <div>Parent Content</div>;
}
Child Components
Component:Child-1
Renders:1
Avg Time Between:0ms
Last Render:0ms ago
Component:Child-2
Renders:1
Avg Time Between:0ms
Last Render:0ms ago
function Child({ id }) {
  useRenderTracking(`Child-${id}`);
  
  return <div>Child Content</div>;
}
State Updates
Component:FormComponent
Renders:1
Avg Time Between:0ms
Last Render:0ms ago
function FormComponent() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');
  
  useRenderTracking('FormComponent');
  
  return <div>
    <button onClick={() => setCount(c => c + 1)}>
      Count: {count}
    </button>
    <input value={text} onChange={e => setText(e.target.value)} />
  </div>;
}

Render Statistics

How to use:

  • Click buttons to trigger component re-renders
  • Watch render counts increase
  • Red numbers indicate > 10 renders
  • Average time shows render frequency
Configuration
useRenderTracking('MyComponent', {
  // Log every render
  logRenders: true,
  
  // Warn if renders exceed threshold
  warnThreshold: 10
});
Console Output
[RenderTracker] MyComponent
Render #23
Time since last: 145ms

[RenderTracker] Warning!
MyComponent has rendered 51 times
Consider optimization

Optimization Tips:

  • Use React.memo for pure components
  • Memoize callbacks with useCallback
  • Memoize values with useMemo
  • Split large components into smaller ones

Advanced Examples​

With Warning Threshold​

function ExpensiveComponent() {
useRenderTracking('ExpensiveComponent', {
logRenders: true,
warnThreshold: 10, // Warn if renders > 10
});

return <div>Expensive content</div>;
}

List Items​

function TodoItem({ todo }: { todo: Todo }) {
useRenderTracking(`TodoItem-${todo.id}`, {
logRenders: false,
warnThreshold: 20,
});

return (
<li>
<input type="checkbox" checked={todo.completed} />
<span>{todo.text}</span>
</li>
);
}

With React.memo​

const OptimizedCard = React.memo(function Card({ data }: CardProps) {
useRenderTracking('Card', {
logRenders: true,
});

// This should render less often due to React.memo
return <div className="card">{data.title}</div>;
});

Context Consumers​

function ThemedButton() {
const theme = useContext(ThemeContext);

useRenderTracking('ThemedButton', {
logRenders: true,
warnThreshold: 15,
});

return (
<button className={`btn-${theme}`}>
Click me
</button>
);
}

Form Fields​

function FormField({ name, value, onChange }: FormFieldProps) {
useRenderTracking(`FormField-${name}`, {
logRenders: true,
warnThreshold: 25,
});

return (
<input
name={name}
value={value}
onChange={onChange}
/>
);
}

Debugging Features​

Render Count​

Track total renders per component:

  • Initial render + re-renders
  • Render frequency over time
  • Average time between renders

Console Warnings​

Get notified when renders exceed threshold:

[RenderTracker] Warning: ExpensiveComponent has rendered 51 times!
Consider optimizing with React.memo, useMemo, or useCallback

Performance Metrics​

  • Total render count
  • Renders per second
  • Time since last render
  • Render frequency trends

Best Practices​

✅ Do's​

  • Track suspect components: Focus on slow/expensive ones
  • Set appropriate thresholds: Based on component complexity
  • Use with React DevTools Profiler: Get complete picture
  • Remove in production: Or set logRenders: false

❌ Don'ts​

  • Don't track every component: Focus on problem areas
  • Don't set threshold too low: Some re-renders are normal
  • Don't ignore warnings: Each indicates potential issue

Optimization Strategies​

Use React.memo​

// Before: Renders on every parent update
function Card({ title }) {
useRenderTracking('Card');
return <div>{title}</div>;
}

// After: Only renders when title changes
const Card = React.memo(function Card({ title }) {
useRenderTracking('Card');
return <div>{title}</div>;
});

Memoize Expensive Calculations​

function DataGrid({ data, filter }) {
useRenderTracking('DataGrid');

// Expensive calculation
const filteredData = useMemo(() => {
return data.filter(item => filter(item));
}, [data, filter]);

return <table>{/* render filteredData */}</table>;
}

Stabilize Callbacks​

function Parent() {
// ❌ New function every render
const handleClick = () => console.log('clicked');

// ✅ Stable function reference
const handleClick = useCallback(() => {
console.log('clicked');
}, []);

return <Child onClick={handleClick} />;
}

function Child({ onClick }) {
useRenderTracking('Child');
return <button onClick={onClick}>Click</button>;
}

Split Components​

// Before: Entire component re-renders
function Dashboard({ user, stats, settings }) {
useRenderTracking('Dashboard'); // High render count!

return (
<div>
<UserInfo user={user} />
<Stats stats={stats} />
<Settings settings={settings} />
</div>
);
}

// After: Only changed parts re-render
function Dashboard({ user, stats, settings }) {
return (
<div>
<MemoizedUserInfo user={user} />
<MemoizedStats stats={stats} />
<MemoizedSettings settings={settings} />
</div>
);
}

TypeScript Support​

Full type safety:

interface RenderTrackingOptions {
logRenders?: boolean;
warnThreshold?: number;
}

function Component() {
useRenderTracking('Component', {
logRenders: true,
warnThreshold: 30,
});

return <div>...</div>;
}

Performance Tips​

Identify Bottlenecks​

  1. Add tracking to suspect components
  2. Interact with your app
  3. Check which components render most
  4. Optimize high-render components

Compare Before/After​

// Before optimization
useRenderTracking('List'); // 156 renders!

// After adding React.memo
useRenderTracking('List'); // 23 renders ✅

Track renders over time to ensure optimizations work:

  • Day 1: 200 renders/minute
  • After optimization: 45 renders/minute
  • Target: < 30 renders/minute

Development Mode​

Only track in development:

function Component() {
if (process.env.NODE_ENV === 'development') {
useRenderTracking('Component', {
logRenders: true,
warnThreshold: 50,
});
}

return <div>...</div>;
}

Next Steps​