Chrome DevTools Performance Panel in Depth: Reading Flame Charts Correctly
AI generated
JS
() =>
JavaScript · Chrome DevTools · Profiling · Web Performance
Chrome DevTools Performance Panel in Depth
Reading Flame Charts, Call Tree and Long Tasks correctly

A recording in the Performance Panel looks at first glance like a colorful bar chart. Combining Flame Chart, Call Tree, Bottom Up and Event Log reveals the actual cause of jank, a blocked main thread and poor Web Vitals, instead of just treating symptoms.

18 min read Performance Panel · Flame Chart · Main Thread · Long Tasks Chrome DevTools 2026

1. Why the Performance Panel is indispensable

The Performance Panel in Chrome DevTools is the only tool that records a complete timeline of every activity on a web page, from JavaScript execution through style recalculation, layout and paint, all the way to network requests and garbage collection. Where browser extensions or simple console logs always show just a slice, a trace from the Performance Panel provides the full context: which code ran when, for how long, and what it blocked on the main thread.

The value of the Performance Panel becomes clear when jank or a delayed response to user input is reported but the cause is unclear. Instead of guessing which function is too slow, a recording in the Performance Panel shows exactly the affected time range, the functions called, and their self time. That precision is what separates systematic profiling from trial and error, and it is why the Performance Panel remains the first stop for any serious web performance work.

Another advantage: the Performance Panel works directly with real browser internals, not estimates. The Flame Chart view is based on the same trace format that Lighthouse and the Chrome User Experience timeline also use. Once you have properly read a Performance Panel trace, you automatically understand field data and synthetic measurements better too, because the same concepts, main thread, task, frame, keep reappearing everywhere.

2. Starting a recording: options and screenshots

A recording in the Performance Panel starts via the circle button or with Ctrl plus E, while the interaction under investigation is performed. It is important to enable the screenshots checkbox before starting. Without screenshots, the Performance Panel only shows abstract bars, with screenshots the filmstrip view shows what the user actually saw at every moment, including blank areas during a Long Task.

For reproducible results it also helps to enable the Web Vitals overlay on the page itself, combined with a clearly scoped interaction in the recording, such as a single button click rather than a long session with many actions. A short, focused recording in the Performance Panel is easier to analyze than a ten second trace with hundreds of overlapping activities. For automated recordings, programmatic recording through the Chrome DevTools Protocol tracing start method delivers the same data a manual Performance Panel recording would.


// Programmatic recording via Chrome DevTools Protocol (Puppeteer)
// Produces the same trace data the Performance Panel visualizes manually
import puppeteer from "puppeteer";

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.tracing.start({
  path: "trace.json",
  screenshots: true,
  categories: ["devtools.timeline", "disabled-by-default-devtools.timeline"],
});

await page.goto("https://example.com/checkout");
await page.click("#place-order");
await page.waitForSelector("#confirmation");

await page.tracing.stop();
// trace.json can be loaded back into the Performance Panel via "Load profile"
await browser.close();

3. Reading the Flame Chart: stack, width and color

The Flame Chart is the central visualization in the Performance Panel. Each bar represents a function call, horizontal position shows the point in time, width shows the duration, and vertical position shows depth in the call stack. A bar that directly calls another bar below it appears as a child in the Flame Chart, stacked exactly like the real call stack at runtime. That structure makes the Flame Chart in the Performance Panel a precise picture of what the JavaScript engine actually did.

The color of the bars in the Performance Panel's Flame Chart follows a fixed category mapping: yellow stands for scripting, meaning JavaScript execution, purple for rendering, meaning style and layout calculation, green for painting, and gray for system or idle time. Seeing a lot of yellow over a long stretch in the Performance Panel points to a JavaScript problem, seeing a lot of purple points more toward a layout problem, for example caused by forced reflows. This color coding in the Flame Chart allows a quick first diagnosis before even diving into the details of a single function call.

A practical trick when reading the Flame Chart: hovering over a narrow bar shows a tooltip with the exact function name, file and line. Clicking a bar automatically jumps the Performance Panel into the Summary view below, which shows exactly that call in detail, including self time without child calls. Anyone who works with the Flame Chart regularly quickly develops a sense of where in the trace worthwhile optimization targets are hiding, without having to click through every single line.

4. Call Tree and Bottom Up: two views on the same data

Below the Flame Chart, the Performance Panel offers three tabs: Bottom Up, Call Tree and Event Log. The Call Tree shows the call hierarchy from top to bottom, just like the Flame Chart, but as an expandable list with percentages. That is helpful for understanding which entry point, for example an event handler or a framework lifecycle hook, caused the most time in the trace.

The Bottom Up view in the Performance Panel flips the perspective: it groups by the function itself and shows from where that function was called overall, regardless of context. That is the fastest way to find the single most expensive function in a recording, for example an inefficient sort function called from multiple places in the code. Without Bottom Up you would have to search the same function name in every branch of the Call Tree individually, with Bottom Up the sum of all calls sits directly at the top of the list.

The Event Log lists every single event in the trace chronologically, including network requests, timers and rendering events. For most Performance Panel analyses the combination of Flame Chart for the visual overview and Bottom Up for concrete function identification is enough, the Event Log is mostly consulted only for very specific questions about individual network or timer events.


// Example function that shows up prominently in Bottom Up
// because it is called from three different UI paths
function sortLargeDataset(items) {
  // Naive comparator recomputes derived values on every comparison
  return items.sort((a, b) => {
    const scoreA = computeRelevanceScore(a); // expensive, no memoization
    const scoreB = computeRelevanceScore(b);
    return scoreB - scoreA;
  });
}

// Fix: precompute scores once before sorting (Schwartzian transform)
function sortLargeDatasetFast(items) {
  const scored = items.map((item) => ({
    item,
    score: computeRelevanceScore(item),
  }));
  scored.sort((a, b) => b.score - a.score);
  return scored.map((entry) => entry.item);
}

5. Main thread activity: scripting, rendering, painting

The main thread is the central track in the Performance Panel and the place where JavaScript, style calculation, layout and most of rendering happen. Anything happening on the main thread blocks the response to user input, because a single thread cannot process a click and run a long loop at the same time. The Performance Panel makes that blocking visible, since the main thread track shows every millisecond of activity without gaps.

A common misconception is that many developers think asynchronous code, for example with async and await, automatically relieves the main thread. That is only true for the wait on external resources like network or timers, not for the actual execution of code afterward. An await on a fetch request does not pause the main thread while waiting, but as soon as the response arrives, the callback runs synchronously and blocks the main thread just like any other synchronous code. The Performance Panel shows exactly this transition in the Flame Chart as a new scripting block after the network track.

To specifically reduce main thread blocking, splitting large synchronous tasks into smaller chunks with intermediate steps helps, for example via requestIdleCallback or the newer Scheduler API with scheduler.yield. The Performance Panel shows the success of such measures immediately: instead of a single wide bar, several shorter bars appear with small gaps in between, where the main thread is available for input again.

6. Spotting and classifying Long Tasks in the trace

A Long Task is by definition any task on the main thread lasting longer than fifty milliseconds. The Performance Panel marks such Long Tasks with a red triangle in the upper right corner of the relevant bar in the main thread track. This visual marker is the fastest way to immediately find the problematic spots in a long recording, without having to check every bar individually.

The fifty millisecond threshold for Long Tasks in the Performance Panel is not an arbitrary value, it is based on the perceptual limit for responsiveness. As long as a task stays under fifty milliseconds, enough buffer remains for the browser to still process an input within a time frame that feels acceptable to humans. Once a task exceeds this threshold noticeably, for example reaching two or three hundred milliseconds, the delay becomes perceptible to users, regardless of how fast the device otherwise is.

In the Performance Panel a Long Task can be expanded and analyzed in the Call Tree below to see exactly which part of the task consumed the most time. Common causes are large JSON parsing operations, inefficient DOM manipulation in loops, or third party scripts that synchronously process large amounts of data. For third party code, the Performance Panel often shows a distinct color marker or at least a recognizable domain name in the function description, which makes attributing responsibility much easier.


// Breaking up a long task so it no longer shows the red triangle
// in the Performance Panel's Main Thread track
async function processLargeArray(items) {
  const chunkSize = 200;
  const results = [];

  for (let i = 0; i < items.length; i += chunkSize) {
    const chunk = items.slice(i, i + chunkSize);
    results.push(...chunk.map(transformItem));

    // Yield back to the main thread between chunks
    if ("scheduler" in window && "yield" in window.scheduler) {
      await window.scheduler.yield();
    } else {
      await new Promise((resolve) => setTimeout(resolve, 0));
    }
  }

  return results;
}

7. Web Vitals markers: LCP, CLS and INP in the recording

The Performance Panel shows dedicated markers for the most important Web Vitals directly in the timeline: a symbol for Largest Contentful Paint, small red areas for layout shifts that together make up Cumulative Layout Shift, and, in newer Chrome versions, markers for Interaction to Next Paint as well. These markers appear as their own row above the main thread track and can be clicked to see details about the relevant element and its timing.

For Largest Contentful Paint analysis, clicking the LCP marker in the Performance Panel shows exactly which DOM element was detected as the largest visible element, and provides a breakdown of the time into time to first byte, resource load time and render delay. This breakdown in the Performance Panel is noticeably more precise than a plain Lighthouse score, because it is based on the actual timing data of the specific recording, not on a simulated environment.

Layout shifts are displayed in the Performance Panel as small red bars directly in the experience track. Clicking one opens the details with the affected elements and their shift in pixels. This view makes it easy to attribute layout shifts to concrete causes, for example an image without defined width and height, or a late inserted ad banner pushing the remaining content down.

8. CPU throttling, network simulation and custom marks

A recording in the Performance Panel on a powerful developer laptop rarely reflects the real user experience. That is why the Performance Panel offers a CPU throttling option that artificially reduces processor performance by a factor of four or six, to simulate an average mobile device. Combined with network throttling for slow 3G or 4G connections, the Performance Panel delivers a much more realistic picture of the actual user experience than an unthrottled recording.

For custom, business relevant timing, the Performance Panel supports the User Timing API. With performance.mark and performance.measure, custom markers can be set that appear in the trace as their own track below main thread activity. That is especially valuable for marking business critical flows, for example the start and end of a checkout process, instead of relying only on generic browser metrics.


// Custom marks show up as a dedicated "Timings" track
// in the Performance Panel, next to Main Thread activity
performance.mark("checkout-start");

await validateCart();
await calculateShipping();
await applyDiscounts();

performance.mark("checkout-end");
performance.measure("checkout-duration", "checkout-start", "checkout-end");

const [entry] = performance.getEntriesByName("checkout-duration");
console.log(`Checkout took ${entry.duration.toFixed(1)}ms`);

9. Performance Panel compared to other tools

The Performance Panel is not the only tool for performance analysis, but it has a clear place in the toolbox. Other tools like Lighthouse or WebPageTest deliver synthetic scores and recommendations, the Performance Panel delivers the granular raw data behind them. The table below outlines when each tool provides the most value.

Tool Data level Strength Limit
Performance Panel Full trace, function level Exact root cause analysis via Flame Chart Manual, one recording per analysis
Lighthouse Synthetic score, recommendations Fast triage, CI integration No function level detail in the score
WebPageTest Real devices, waterfall Location and device variance No interactive Flame Chart
Chrome UX Report Field data, real users Real distribution across all users No root cause analysis for individual cases

In practice these tools complement each other. The Chrome UX Report shows that a problem exists, Lighthouse gives an initial direction, and the Performance Panel ultimately delivers the function and line that actually needs to be fixed. Anyone who only works with Lighthouse scores without ever opening a Performance Panel recording often optimizes symptoms instead of the actual cause.

Mironsoft

JavaScript performance analysis and frontend profiling

Getting to the bottom of jank and slow interactions?

We analyze your application with the Performance Panel, find the exact Long Tasks and deliver concrete, prioritized measures instead of generic recommendations.

Trace analysis

Create a recording, evaluate Flame Chart and Bottom Up systematically

Long Task fixes

Split up tasks, apply the Scheduler API, relieve the main thread

Web Vitals monitoring

Custom marks, keep LCP and INP tracking in view permanently

10. Summary

The Performance Panel in Chrome DevTools remains the most precise tool for finding the actual cause of jank and slow interactions. The Flame Chart shows the complete call stack over time, Bottom Up identifies the most expensive function regardless of call context, and the main thread track makes Long Tasks immediately visible with the red triangle. Web Vitals markers for LCP, CLS and INP connect the technical level directly with the metrics that actually measure user experience.

Anyone who works with the Performance Panel regularly develops a feel for where optimization has the biggest effect, without manually going through every line of code. Combined with CPU throttling for realistic conditions and custom marks for business critical flows, a single recording becomes a solid foundation for prioritized performance work, instead of vague assumptions about the slowest part of the application.

Performance Panel in Depth — The Essentials at a Glance

Flame Chart

Width shows duration, depth shows call stack, color shows category: yellow scripting, purple rendering, green painting.

Bottom Up vs. Call Tree

Bottom Up finds the most expensive function across all calls, Call Tree shows the hierarchy of one entry point.

Long Tasks

Red triangle from fifty milliseconds of main thread blocking, clickable directly in the trace for detail analysis.

Web Vitals in the trace

LCP, CLS and INP markers directly in the timeline, with a breakdown of the exact cause per element.

11. FAQ: Chrome DevTools Performance Panel

1What exactly does the Performance Panel show?
A complete timeline of all browser activity: JavaScript, style, layout, painting, network and garbage collection as an interactive Flame Chart.
2How do I read the Flame Chart?
Width shows duration, depth shows call stack position, color shows category: yellow scripting, purple rendering, green painting.
3Bottom Up vs. Call Tree?
Call Tree shows hierarchy from an entry point, Bottom Up groups by function across all call contexts.
4How do I spot a Long Task?
A red triangle top right on a bar in the main thread track, from fifty milliseconds duration onward.
5Why does async code block the main thread?
await only pauses while waiting, the callback afterward runs synchronously and blocks like any other code.
6Finding a layout shift cause?
Small red bars in the experience track, clicking one shows affected elements and pixel shift.
7What is CPU throttling for?
Simulates an average mobile device by artificially reducing processor performance, usually factor four or six.
8Adding custom markers?
performance.mark and performance.measure produce their own Timings track with business critical flows.
9Does it replace Lighthouse?
No, Lighthouse delivers score and recommendations, the Performance Panel the granular raw data behind it.
10Finding third party scripts?
The domain name appears directly in the Flame Chart and in Bottom Up, wide foreign bars are a strong indicator.