Measuring Frontend Performance Using Chrome Developer Tools

2016. 11. 15.

Measuring Frontend Performance Using Chrome Developer Tools

Timeline

The Timeline is a tool that records and visualizes browser operations triggered by webpage loading or user interactions in a timeline format. It allows you to monitor browser events (not just DOM events but also internal browser operations, including those that trigger DOM events), CPU usage, memory consumption, network activity, and FPS over time. Additionally, it provides stack traces of JavaScript function calls for events, making it easy to identify which JavaScript code is affecting performance. Let's explore the features of the Timeline through two performance measurement examples.

Measuring innerHTML Performance

The innerHTML property is a commonly used DOM element attribute for web developers. It enables the creation or modification of child elements as HTML text within a specific element. However, depending on its usage, it can exhibit extremely poor performance due to how browsers handle this property. When the value of innerHTML is directly modified in any way, all existing child elements are deleted, and the browser parses the new innerHTML content to recreate elements. This behavior results in severe performance issues in scenarios like the following code:

for(var i=0;i<1000;i+=1) {
    document.body.innerHTML += '<div>~Pen Pineapple Apple Pen~</div>'
}

Appending HTML text to innerHTML causes all pre-existing child elements to be re-parsed and recreated along with the new text. Although the loop ultimately displays 1,000 <div> tags, the browser actually parses and creates or deletes 500,500 <div> tags during execution. As the loop progresses, parsing increases significantly, leading to longer execution times. The repeated parsing cost and increasing time per parse result in the worst-case performance. One solution is to pre-create the HTML text and apply it to innerHTML all at once:

var str = '';

for(var i=0;i<1000;i+=1) {
    str += '<div>~Pen Pineapple Apple Pen~</div>';
}

document.body.innerHTML = str;

Executing this code visibly demonstrates much faster performance compared to the first implementation. Now let's examine how these two implementations differ in the Timeline.

Basic Usage of Timeline

Using the Timeline involves starting recording by clicking the record button, performing the desired actions to measure, stopping recording, and reviewing the results. You can also select additional information to record using checkboxes in the control bar at the top.

img

To include JavaScript stack traces for recorded events, activate the JS Profile checkbox. Other checkboxes indicate what additional data will be recorded (e.g., screenshots for monitoring visual changes over time). Start recording by clicking the round button on the left of the control bar.

img

Once recording starts, a status window appears. After completing your actions, click Stop to view the measured results.

Overview and Flame Chart

The following image shows measurements from the first implementation of innerHTML, which had performance issues:

img

Below the control bar is an overview showing CPU usage, FPS variations, and network activity over time. The overview provides a general picture of what happened during measurement. Below it lies a flame chart displaying detailed events as bars and a detail view for in-depth information about each event.

In this example, a red bar labeled "1171.3ms" indicates a single frame that took too long to process (one frame represents the time taken to refresh one screen). The green FPS graph in the overview drops sharply due to this long frame.

img

Zooming into the flame chart reveals multiple occurrences of blue Parse HTML events during loop execution within the hitListener function. These events occur every time innerHTML is updated within the loop because browsers must re-parse HTML text each time it changes. Since this loop runs 1,000 times, at least 1,000 Parse HTML events are triggered.

Comparing durations of the first and last Parse HTML events:

img

img

The first event takes 0.04ms while the last takes 1.24ms—a significant difference caused by increasing parsing workloads as more elements are created.

Now let's examine results from the improved implementation:

img

Overall performance improves significantly due to reduced browser operations. The total frame duration drops from 1171.3ms to just 21.9ms—a drastic improvement. Only one Parse HTML event occurs during execution (taking just 0.98ms), as all HTML text is applied at once.

Layout Events

Layout events (also known as reflows) occur when an element's size or position changes—triggering recalculations of layout-related properties across affected elements (e.g., block or inline elements). These events impact performance depending on their frequency or duration.

Detail View and Tracking Layout Events

While unavoidable for visual effects, unnecessary layout events should be minimized. The following flame chart represents an ideal scenario:

img

Here, clicking a button changes an element's height via JavaScript (hitListener). A single layout event occurs after script execution due to height modification.

Clicking on layout events in flame charts reveals detailed information in Summary tabs within Detail Views:

img

In this example, modifying height inherently triggers layout recalculations—leaving no room for improvement.

Now consider problematic implementations with unnecessary layout recalculations:

img

Here, modifying both height and width introduces additional mid-script layout recalculations (Layout Forced) flagged as potential bottlenecks:

img

This issue arises because reading layout properties (offsetWidth) before applying changes forces immediate recalculations mid-script execution.

Reordering code resolves this issue:

var newHeight = el.offsetHeight + 10; // No special operation
var newWidth = el.offsetWidth + 10;   // No special operation

el.style.height = newHeight + 'px';   // Schedule layout update after script execution
el.style.width = newWidth + 'px';     // No special operation

// Layout recalculation occurs once after script execution

By batching property reads before applying changes, layouts are recalculated only once—restoring ideal flame chart behavior.

Conclusion

Frontend performance bottlenecks arise from numerous factors that cannot all be enumerated here. However, Chrome's Timeline remains an unparalleled tool for diagnosing browser-level issues affecting performance. For further details on event types displayed in flame charts, refer to Google's Developer Site. By identifying costly events through Timeline analysis and addressing them iteratively, significant performance improvements can be achieved.

♥ Support writer ♥
with kakaopay

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

shiren • © 2025Sungho Kim