Recommended resources
The freely available resources this lesson will direct you to.
Hello! Welcome back to our course on mastering Chrome DevTools.
In our last lesson, we explored the Performance Monitor, your real-time dashboard for spotting the symptoms of performance issues like high CPU usage or memory leaks. We saw how it helps you know that a problem is occurring and when. Today, we'll go a level deeper to find the cause.
This lesson focuses on the heart of performance analysis in DevTools: the Performance panel's flame chart. You'll learn how to record a detailed performance profile and interpret this powerful visualization to pinpoint the exact, long-running JavaScript functions that are slowing down your application. Given your extensive experience as a front-end lead, mastering this tool is a critical step for diagnosing and resolving complex performance bottlenecks with precision.
Part 1: Understanding Flame Charts
Before we dive into a full analysis, let's establish what a flame chart is. It's a visual representation of your code's execution, showing call stacks over time. Understanding its structure is key to interpreting it correctly.
For a quick and clear introduction, please watch this short video from Addy Osmani on the Google Chrome Developers team. Although it mentions the older "Profiles" panel, the core concepts of the flame chart itself remain identical and are explained perfectly.
Visualising JS processing over time with DevTools Flame Charts
This video, 'Visualising JS processing over time with DevTools Flame Charts', provides an excellent conceptual overview of what flame charts are and how to interpret their basic structure.
Watch the entire video (it's less than 3 minutes). Pay close attention to the explanation of the horizontal and vertical axes, and the difference between 'Self Time' and 'Total Time'.
To summarize the key concepts from the video:
- The Y-Axis (Vertical) is the Call Stack: Functions at the top of a stack were called by the functions directly below them. It shows you what called what.
- The X-Axis (Horizontal) is Time: The width of a function block represents the total time it took to execute, including any functions it called. Wider blocks are your primary targets for investigation.
- Self Time: The time spent executing the code directly within that specific function, not including any functions it called. A high self time often indicates a loop or heavy computation within the function itself.
- Total Time: The total time from when the function was invoked until it completed, including the execution time of all other functions it called.
This distinction between Self and Total time is fundamental. A function might have a high Total Time but a low Self Time, which tells you it isn't the problem itself but is calling other functions that are slow.
Part 2: Recording a Performance Profile
Now that we understand the chart, let's learn how to generate one using the Performance panel. Unlike the Performance Monitor, which is always on, the Performance panel requires you to explicitly record a session.
You can record two main types of performance profiles:
- Runtime Performance: You start the recording, interact with your page (e.g., click a button, scroll a list), and then stop the recording. This is for analyzing performance during user interactions.
- Load Performance: You click a dedicated "record and reload" button, and DevTools captures the performance trace as the page loads from scratch.
For a professional-grade analysis, it's best practice to run your tests in an Incognito window to prevent Chrome extensions from interfering with the results. It's also wise to throttle the CPU and Network to simulate how your application performs on less powerful devices and slower connections.
To see how to set this up, watch the first part of this "DevTools Tips" video.
Record and analyze a performance trace #DevToolsTips
This video, 'Record and analyze a performance trace', demonstrates the modern workflow for recording in the Performance panel, including best practices like using Incognito mode and throttling.
Watch from the start until 01:07. Focus on how to prepare the environment and initiate the recording. We'll cover the analysis part later in this lesson.
When you open the recording settings, you'll see a checkbox for "Disable JavaScript samples." For our purposes of analyzing function calls, you should ensure this is unchecked. Disabling it would hide the detailed JavaScript call stacks we want to see.
Part 3: Analyzing the Flame Chart to Find Bottlenecks
Once you've recorded a trace, the Main track in the Performance panel will display your flame chart. This is where the real investigation begins.
The Main track in the Performance panel. The flame chart shows JavaScript execution (yellow), rendering (purple), and other main thread activities over time. The red triangles highlight 'Long Tasks'.
Identifying Long Tasks
One of the most helpful features is that DevTools automatically flags Long Tasks. These are any tasks on the main thread that take longer than 50 milliseconds. Why 50ms? To maintain a smooth 60 frames per second (FPS), the browser has about 16.7ms to do everything for a single frame. If a JavaScript task hogs the main thread for over 50ms, the browser can't respond to user input or render updates, leading to a sluggish or frozen experience.
These long tasks are marked with a red triangle in the flame chart, making them an excellent starting point for your analysis.
A Practical Walkthrough: From Visuals to Data
Now, let's move from theory to a practical, real-world example. The following article provides a superb deep-dive into analyzing and optimizing a slow canvas animation using the exact techniques we're discussing. As a senior developer, you'll appreciate the methodical approach.
Comprehensive guide to JavaScript performance analysis using Chrome DevTools
This comprehensive guide uses a real-world canvas library to demonstrate a full performance analysis workflow. We'll focus on the sections explaining how to interpret the flame chart and the Bottom-Up panel.
Please read two key sections from this article: Start with 'Analysing the flame chart'. Pay attention to how the author follows the widest blocks in the chart (_renderObjects -> render) to narrow down the problem area. Note the patterns they look for: single, wide nodes and frequent, repeated nodes. Next, read 'Bottom-Up analysis'. This is crucial. It explains how to switch from the visual flame chart to a data-driven table to get concrete numbers on Self Time and Total Time for all functions. See how this confirms the suspicions from the flame chart analysis.
This walkthrough demonstrates the ideal two-step workflow for analysis:
-
Visual Analysis (The Flame Chart): Start with the flame chart. Select a long task and look at the call stack. Follow the "path of the widest blocks" down the stack to visually identify the sequence of calls consuming the most time. This gives you a qualitative sense of where the problem lies.
-
Quantitative Analysis (The Bottom-Up Tab): After you've identified a suspicious area in the flame chart (by selecting a function block), switch to the Bottom-Up tab at the bottom of the panel. This view aggregates the time spent in every function and presents it in a table. Sorting this table by Self Time and Total Time is the most effective way to find your biggest offenders:
- Sort by Self Time: The functions at the top are spending the most time in their own code (e.g., heavy loops, complex calculations). These are often prime candidates for optimization.
- Sort by Total Time: The functions at the top are the overall most expensive call stacks. A function with high Total Time but low Self Time is a "manager" function—it's slow because it calls other slow functions. Expanding its call stack in the Bottom-Up tab will show you which of its children are the real culprits.
By combining the visual intuition of the flame chart with the hard data from the Bottom-Up tab, you can move from a vague "it's slow" to a precise "function calculateMatrix is taking 200ms and is our main bottleneck."
Test your understanding!
You're analyzing a performance recording. In the Bottom-Up tab, you see the following for two functions:
renderComponent(): Total Time: 350ms, Self Time: 10msprocessData(): Total Time: 340ms, Self Time: 335ms
Based on this data, which function likely contains the inefficient code that needs optimization, and why?
Show answer
The function processData() is the one to investigate.
Reasoning:
processData()has a very high Self Time (335ms), which is nearly equal to its Total Time. This indicates that the vast majority of the time is being spent inside this function, likely in a computationally expensive loop or algorithm.renderComponent()has a high Total Time but a very low Self Time. This tells us thatrenderComponent()itself is fast, but it calls other functions that are slow. In this case, it's almost certain thatrenderComponent()callsprocessData(), making it the source of the bottleneck.
Conclusion
In this lesson, we made the jump from identifying performance symptoms to pinpointing their cause. The flame chart and its associated data tables are the most powerful tools in your arsenal for deep-diving into JavaScript performance.
Key Takeaways:
- Flame charts visualize your call stack (Y-axis) over time (X-axis). The width of a function block shows how long it took to execute.
- Begin your analysis by looking for Long Tasks (>50ms), which are automatically highlighted with red triangles in the Main track.
- Use a two-step analysis process: first, a visual inspection of the flame chart to follow the widest blocks, then a quantitative analysis using the Bottom-Up tab.
- In the Bottom-Up tab, sort by Self Time to find functions with expensive internal logic and by Total Time to find the most costly call stacks overall.
In our next lesson, we'll broaden our focus on the Main thread. JavaScript isn't the only thing that can cause bottlenecks. We will learn to analyze the entire rendering pipeline to diagnose issues like forced synchronous layouts (also known as "layout thrashing"), a common and severe performance killer in complex web applications.