Skip to main content

Overview

Profiling tools are essential for identifying performance bottlenecks in your applications. This guide covers the most powerful profiling tools available for web development, from browser-native solutions to React-specific profilers.
Effective profiling requires understanding what to measure and when. Always profile in production mode and use real-world conditions for accurate results.

Chrome DevTools Performance tab

The Chrome DevTools Performance tab provides a comprehensive deep dive into your application’s runtime performance.
1

Start recording

Open Chrome DevTools (F12), navigate to the Performance tab, and click the record button. Perform the interactions you want to profile, then stop recording.
2

Analyze the flame graph

The flame graph shows function call stacks over time. Wider bars indicate longer execution times. Look for long tasks (yellow blocks) that block the main thread.
3

Identify bottlenecks

Focus on:
  • Long tasks that exceed 50ms
  • Layout thrashing (multiple forced reflows)
  • Expensive JavaScript execution
  • Rendering and painting bottlenecks
4

Review network activity

Check the network timeline to see how resource loading impacts performance. Look for render-blocking resources and waterfall patterns.
Use the “Bottom-Up” and “Call Tree” tabs to find which functions consume the most time. Sort by “Self Time” to identify the most expensive operations.

Key metrics to monitor

Main thread activity

Monitor for long tasks that block user interaction. Tasks over 50ms can cause jank.

Frame rate

Target 60fps (16.6ms per frame) for smooth animations. Dropped frames indicate performance issues.

JavaScript heap

Watch for memory leaks and excessive allocations that trigger frequent garbage collection.

Network timing

Identify slow resources and optimization opportunities in the loading sequence.

React DevTools Profiler

The React DevTools Profiler is specifically designed to measure React component performance and identify unnecessary re-renders.

Profiling workflow

1

Enable profiling

Install the React DevTools browser extension and open the Profiler tab. Click the record button before performing actions.
2

Capture interactions

Perform the user interactions you want to analyze. The profiler records all component renders during this time.
3

Analyze renders

Review the flame graph to see which components rendered and how long each took. Color intensity indicates render duration.
4

Identify unnecessary renders

Look for components that rendered but didn’t commit changes. These are optimization opportunities.
Shows the component hierarchy with render durations. Wider bars indicate more time spent rendering.
Use this view to:
- Identify slow components
- Understand render cascades
- Find expensive subtrees
Always profile in production mode. Development mode includes additional checks that significantly impact performance metrics.

Lighthouse metrics

Lighthouse provides automated performance auditing with key metrics that reflect user experience.

Core Web Vitals

Measures when the first content appears on screen. Target: under 1.8 seconds.Optimization strategies:
  • Minimize render-blocking resources
  • Optimize server response time
  • Use efficient cache policies
  • Eliminate unnecessary JavaScript
Measures when the largest content element becomes visible. Target: under 2.5 seconds.Optimization strategies:
  • Optimize images and videos
  • Preload critical resources
  • Reduce server response time
  • Use CDN for static assets
Measures when the page becomes fully interactive. Target: under 3.8 seconds.Optimization strategies:
  • Minimize JavaScript execution time
  • Code split and lazy load
  • Remove unused code
  • Optimize third-party scripts
Measures visual stability and unexpected layout shifts. Target: under 0.1.Optimization strategies:
  • Set explicit dimensions for images and videos
  • Reserve space for dynamic content
  • Avoid inserting content above existing content
  • Use CSS transform instead of layout properties
Measures interactivity and response time to first user interaction. Target: under 100ms.Optimization strategies:
  • Break up long tasks
  • Optimize JavaScript execution
  • Use web workers for heavy computation
  • Implement code splitting

Running Lighthouse

# Open Chrome DevTools (F12)
# Navigate to Lighthouse tab
# Select categories and device type
# Click "Analyze page load"
Best for quick audits during development.

Custom performance marks and measures

The User Timing API allows you to create custom performance measurements for application-specific metrics.

Basic usage

// Mark the start of an operation
performance.mark('search-start');

// ... perform search operation ...

// Mark the end of an operation
performance.mark('search-end');

// Create a measure between marks
performance.measure('search-duration', 'search-start', 'search-end');

// Get the measurement
const measure = performance.getEntriesByName('search-duration')[0];
console.log(`Search took ${measure.duration}ms`);

Advanced patterns

import { useEffect } from 'react';

function SearchComponent() {
  useEffect(() => {
    performance.mark('search-component-mount');
    
    return () => {
      performance.mark('search-component-unmount');
      performance.measure(
        'search-component-lifetime',
        'search-component-mount',
        'search-component-unmount'
      );
    };
  }, []);
  
  const handleSearch = async (query) => {
    performance.mark('search-query-start');
    
    const results = await fetchResults(query);
    
    performance.mark('search-query-end');
    performance.measure('search-query', 'search-query-start', 'search-query-end');
    
    return results;
  };
  
  return <SearchUI onSearch={handleSearch} />;
}

Heap snapshots and allocation timelines

Memory profiling helps identify memory leaks and optimize memory usage.

Taking heap snapshots

1

Open Memory profiler

In Chrome DevTools, navigate to the Memory tab and select “Heap snapshot”.
2

Take baseline snapshot

Capture a snapshot in the initial state of your application.
3

Perform actions

Interact with your application, then take another snapshot.
4

Compare snapshots

Use the comparison view to see what objects were allocated and retained between snapshots.

Analyzing allocation timelines

// Example: Detecting memory leaks
class DataStore {
  constructor() {
    this.cache = new Map();
    this.listeners = []; // Potential leak if not cleaned up
  }
  
  subscribe(callback) {
    this.listeners.push(callback);
    
    // Return cleanup function
    return () => {
      const index = this.listeners.indexOf(callback);
      if (index > -1) {
        this.listeners.splice(index, 1);
      }
    };
  }
  
  clear() {
    this.cache.clear();
    this.listeners = [];
  }
}

Common memory leak patterns

  • Event listeners not removed
  • Closures holding references
  • Detached DOM nodes
  • Growing caches without limits
  • Timers not cleared
Use the “Allocation instrumentation on timeline” to see exactly when and where allocations happen during a profiling session.

Next steps

Optimization techniques

Learn strategies to improve performance after identifying bottlenecks

Critical rendering path

Optimize resource loading and rendering for faster initial page loads

Build docs developers (and LLMs) love