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