What Is the User Timing API in JavaScript?

The User Timing API is a browser-native standard that allows developers to measure custom performance metrics within their web applications using high-resolution timestamps. This article explains what the User Timing API is, how it works, and how it registers custom marks and measures directly into browser execution profiles and developer tools.

Understanding the User Timing API

The User Timing API extends the native Performance interface (window.performance). While browsers automatically record built-in navigation and resource metrics, the User Timing API enables developers to define custom points of interest specific to their application’s business logic, such as component render times or API response handling.

Unlike Date.now() or console.time(), the User Timing API relies on DOMHighResTimeStamp, measuring time in milliseconds with microsecond precision relative to the timeOrigin of the document.

How Custom Marks and Measures Work

The API operates primarily through two methods: marks and measures.

1. Creating Custom Marks

A mark is a named timestamp placed at a specific point in JavaScript execution. You create a mark using performance.mark():

// Set a starting mark
performance.mark('dataFetch_start');

// Execute logic
fetchData();

// Set an ending mark
performance.mark('dataFetch_end');

Calling performance.mark() registers a PerformanceMark object in the browser’s performance timeline containing the mark name, entry type (mark), and the exact start timestamp.

2. Creating Custom Measures

A measure calculates the elapsed time between two marks or between a mark and the current moment. You create a measure using performance.measure():

// Calculate duration between the two marks
performance.measure('dataFetch_duration', 'dataFetch_start', 'dataFetch_end');

This creates a PerformanceMeasure object storing the duration and timestamps of the evaluated window.

Registering Marks in Execution Profiles

When profiling JavaScript with developer tools such as Chrome DevTools or Firefox Profiler, the browser integrates User Timing entries directly into the performance timeline:

  1. DevTools Timings Track: During a recording in the Performance panel, custom marks and measures are visually rendered inside the dedicated “Timings” track alongside system events like First Contentful Paint (FCP) and Largest Contentful Paint (LCP).
  2. Flame Chart Correlation: Because User Timing entries are locked to the global timeline, developers can correlate custom application milestones directly with JavaScript call stacks, garbage collection events, and long tasks on the main thread.
  3. Detail Metadata: In modern browsers, performance.mark() and performance.measure() accept a detail parameter containing custom JSON-serializable objects. This metadata is embedded into the profile entry for debugging contextual information.
performance.mark('processItems_start', {
  detail: { itemCount: items.length }
});

Retrieving and Clearing Entries

Recorded marks and measures can be queried programmatically via JavaScript:

// Retrieve all entries with a specific name
const marks = performance.getEntriesByName('dataFetch_start', 'mark');

// Retrieve all measures
const measures = performance.getEntriesByType('measure');

To prevent memory leaks in long-running single-page applications, entries can be cleared from the timeline buffer when no longer needed:

performance.clearMarks('dataFetch_start');
performance.clearMeasures('dataFetch_duration');