Analyzing UI responsiveness (JavaScript)

This topic describes the UI Responsiveness Profiler. This tool is available for Windows Store apps built for Windows using JavaScript in Visual Studio 2012 Update 2.

The UI Responsiveness Profiler can help you isolate performance problems or platform side effects in your app that typically occur with these symptoms:

  • Lack of responsiveness in the UI. The app might be slow to respond if the UI thread is getting blocked. Some things that might block the UI thread include excessive synchronous JavaScript code, excessive CSS layout or CSS calculation work, synchronous XHR requests, garbage collection, excessive paint times, or processor-intensive JavaScript code.

  • Visual updates are less frequent than expected. This occurs if the UI thread is too busy to maintain a smooth frame rate. For example, if the UI thread is busy, frames might be dropped. Some non-UI thread work can also limit the frequency of visual updates, such as network requests and image decoding.

This topic includes these sections:

The graphs in the UI Responsiveness Profiler help you to identify periods of time that might be worth additional investigation. The UI Responsiveness Profiler includes the following graphs:

You can use the UI Responsiveness Profiler when you have a working Windows Store app open in Visual Studio or installed on a computer running Windows 8.

To run the UI Responsiveness Profiler

  1. If you're running the app from Visual Studio, click Local Machine, Simulator, or Remote Machine in the Start Debugging drop-down list on the Standard toolbar.

    For more info about these options, see Running Windows Store apps from Visual Studio.

  2. On the Debug menu, point to JavaScript Analysis > Visual Profiler, and then click one of these:

    • Launch Startup Project. Click this option to analyze the current startup project. If you're running the app on a remote machine, you must click this option.

    • Launch Installed App Package. Click this option to select an installed app that you want to analyze. You can't use this option when you're running the app on a remote machine.

      You can use this option to analyze the performance of apps that you have installed on your computer when you don't have access to source code. This option can also be useful when you just want to analyze the performance of any app, outside of your own app development.

    • Attach to Running App. Click this option to select the app from a list of running apps. You can't use this option when you're running the app on a remote machine.

      You can use this option to analyze performance of apps that are running on your computer when you don't have access to source code.

    When you start the UI Responsiveness Profiler, you might see a User Account Control window requesting your permission to run VsEtwCollector.exe. Click Yes.

  3. Switch to Visual Studio by pressing Alt+Tab.

    The UI Responsiveness Profiler appears on the Diagnostics hub tab.

  4. To stop profiling the app and view data gathered by the profiler, click Stop.

    For a recommended profiler workflow, see UI Responsiveness Profiler workflow in this topic.

The ruler at the top of the Diagnostics hub shows the timeline for profiled information. This timeline applies to both the CPU utilization graph and the Visual throughput graph.

Here's what the diagnostic session timeline looks like:

Diagnostic session ruler

The timeline shows when app lifecyle events occur, like the activation event, and it shows profile marks (user mark triangles) that you can add to your code. For more info about profile marks, see How to add a profile mark in this topic.

The CPU utilization graph provides information about the app's average CPU consumption over a period of time. Information is color-coded to represent the following specific categories: Loading, Scripting, garbage collection (GC), Styling, Rendering, Image decoding, and Other. For more info about these categories, see Profiler events in this topic.

The CPU utilization graph shows the amount of time spent on all app threads, combining CPU utilization values for one or more CPUs into a single percentage value. The CPU utilization value might exceed 100 percent when more than one CPU is in use.

Here's what the CPU utilization graph looks like:

CPU utilization graph

Use this graph to:

  • Identify general areas of concern.

  • Choose a specific time period to display in the timeline details graph. Click a part of the graph and drag the pointer to select a specific time period.

  • Zoom in for a more detailed view of a selected time period by clicking the Zoom in button.

The graph is best used to identify general areas of concern. To find more specific areas of concern, select an area of interest. For more info, see UI Responsiveness Profiler workflow in this topic.

The visual throughput graph shows the frames per second (FPS) for the app. This graph is most useful for the development of games and rich media apps.

The displayed FPS value might differ from the actual frame rate. Keep this information in mind when examining data in this graph:

  • The graph shows the FPS that the app is capable of achieving at any specific time. When the app is idle, the FPS is the same as the monitor refresh rate.

  • The graph shows the actual FPS if the app is doing work that requires visual updates.

  • The graph shows a value of zero if frames are being dropped.

Here's what the visual throughput graph looks like:

Visual throughput graph

Use the visual throughput graph to:

  • Identify general areas of concern.

  • Choose a specific time period to display in the timeline details graph. To select a time period, click a part of the graph and drag the pointer to make a selection.

  • Zoom in for a more detailed view of a selected time period by clicking the Zoom in button.

The timeline details graph, appearing in the lower pane of the UI Responsiveness Profiler, provides sequential and hierarchical information about which events consumed the most CPU time during selected time periods. The timeline details graph can help you determine what triggered a particular event. This graph also helps you to determine the time required to paint visual updates on the screen.

The timeline details graph shows UI thread work and work on background threads that can contribute to slow visual updates. The graph doesn't show JavaScript JIT work, asynchronous GPU work, work performed outside the host process (such as RuntimeBroker.exe and dwm.exe work), or work for areas of the Windows Runtime that haven't yet been instrumented for profiling (such as disk I/O).

Here's what the timeline details graph looks like when an event is selected:

Timeline details graph

If a portion of the timeline for the CPU utilization and visual throughput (FPS) graph is selected, the timeline details graph shows detailed information for the selected time period.

The events in the timeline details graph are color-coded to represent the same categories of work that are shown in the CPU utilization graph. For more info about the event categories and the specific events, see Profiler events in this topic.

Use the timeline details graph to:

  • View approximate start times, duration, and end times for an event in a timeline and grid view. The timeline details graph can show periods ranging from 30 milliseconds to 30 seconds in the grid view, depending on the zoom state.

  • Expand an event in the hierarchy to view children of the event. The event children are other events that are raised by the parent event. For example, a DOM event might have event listeners that appear as children. An event listener might have other events that result from it, like a layout event.

  • View details for each event in the lower-right pane.

  • Rest the mouse pointer over an event to view a tooltip that contains an event description and numerical values that represent the start time, duration, and end time for that particular event.

  • Sort events by start time (the default) or duration. Use the Sort by drop-down list to select a sorting method.

These steps provide a suggested workflow that might help you use the UI Responsiveness Profiler more effectively:

  1. Open your app in Visual Studio. If you want to show connections between app code and specific events in the profiler, add profile marks to your code.

  2. Run the UI Responsiveness Profiler. For more info, see How to run the UI Responsiveness Profiler in this topic.

  3. If necessary, put the app into a desired state.

  4. Switch to Visual Studio (press Alt+Tab) and select Stop in the Diagnostics hub tab of the UI Responsiveness Profiler.

  5. Use the graphs to get a holistic view of app performance. These graphs provide a broad overview of information and can be helpful in identifying a general area of concern.

    • Use the CPU utilization graph to view general information about CPU activity and the type of work it is handling during a given period of time.

    • If you're developing a game or rich media app, use the visual throughput (FPS) graph to track frame rates over time.

  6. Select an area of interest in one of the graphs by clicking a part of the graph and dragging the pointer to make a selection. When you select a time period by making a selection, the timeline details graph in the profiler's lower pane changes to show only the selected time period.

  7. Use the timeline details graph to get detailed information. You can get details about each event in tooltips and a details pane that appears on the right side of the timeline details graph when a particular event is selected. For DOM events, the event's context property appears in parentheses in a tooltip.

  8. With an area selected in the CPU utilization or visual throughput (FPS) graph, click Zoom in to get more detailed information. The timeline for the graph changes to show only the selected time period.

  9. When zoomed in, select a portion of the CPU utilization or visual throughput graph. When you make a selection, the timeline details graph in the profiler's lower pane changes to show only the selected time period.

To help isolate a section of app code that's associated with data that appears in the graphs, you can add a function call in your app that instructs the profiler to insert a profile mark—a user mark triangle—in the timeline at the moment the function gets executed. Any profile mark that you add appears in the timeline for the CPU utilization graph, the visual throughput graph, and the timeline details graph.

To add a profile mark, add this line of code to your app:

msWriteProfilerMark("VisualProfiler:mark,message_string");

This command takes a one string argument that contains required input followed by the message_string parameter, a description of the event. The description appears as a tooltip when you rest the mouse pointer over the profile mark. You can add as many profile marks as you need.

App lifecycle events appear in the diagnostic session timeline as diamond symbols. These are DOM events, which include the DOMContentLoaded event and the Load event. They typically occur in the activated event handler in your code.

Profiler events are categorized and color-coded in the UI Responsiveness Profiler. These are the event categories:

  • Loading. Indicates time spent retrieving app resources and parsing HTML and CSS when the app first loads. This can include network requests.

  • Script. Indicates time spent parsing and running JavaScript. This includes DOM events, timers, script evaluation, and animation frame work. It includes both user code and library code.

  • GC. Indicates time spent on garbage collection.

  • Styling. Indicates time spent parsing CSS and calculating element presentation and layout.

  • Rendering. Indicates time spent on painting the screen.

  • Image decoding. Indicates time spent decompressing and decoding images.

  • Other. Indicates miscellaneous work on the UI thread, such as infrastructure work. This category is non-actionable work and is included because it affects CPU utilization values.

For the script and styling categories, the UI Responsiveness Profiler might provide data that you can act on in the timeline details graph. If you identify scripting issues as a problem, you can use the Visual Studio profiler to obtain more detailed information. For more info, see Analyzing JavaScript performance data in Windows Store apps.

For the other event categories, you might be able to identify platform side effects that result from adding features to your app, but in these cases you might not be able to resolve the particular performance issues by using the UI Responsiveness Profiler.

This table shows the events and their descriptions:

Event

Event category

Description

HTTP request

Loading

A remote resource was found in the DOM, or an XMLHttpRequest was created that resulted in an HTTP request.

HTML parsing

Loading

New HTML content was encountered and an attempt was made to parse the content into nodes and insert the content into the DOM tree.

CSS parsing

Loading

New CSS content was encountered and an attempt was made to parse the CSS content.

Speculative downloading

Loading

The page's HTML content was searched for required resources so that subsequent HTTP requests for the resources could be scheduled quickly.

DOM event

Script

A DOM event occurred and was executed.

The context property for the DOM event, such as DOMContentLoaded or click, is shown in parentheses.

Event listener

Script

An event listener was called and executed.

Timer

Script

A scheduled timer elapsed, and this resulted in the execution of its associated callback function.

Script evaluation

Script

A new SCRIPT element was found in the DOM, and an attempt was made to parse and execute the script.

Animation frame callback function

Script

The browser was going to render another frame, and this triggered an app-provided callback function.

Windows Runtime event

Script

An event that occurred on a Windows Runtime object triggered a registered listener.

Windows Runtime async callback function

Script

An async operation that triggered a Promise callback function was completed by a Windows Runtime object.

Garbage collection

GC

Time was spent collecting memory for objects that were no longer in use.

Layout

Styling

Changes were made to the DOM that required the size and/or position of all affected elements to be recalculated.

CSS calculation

Styling

Changes were made to the DOM that required the style properties of all affected elements to be recalculated.

Paint

Rendering

Visual changes were made to the DOM, and an attempt was made to re-render portions of the page.

Render layer

Rendering

Visual changes were made to an independently rendered fragment of the DOM (called a layer), and the changes required a portion of the page to be rendered.

Frame

Rendering

Pending visual changes to the DOM were processed so that the app's display could be updated.

Image decoding

Image Decoding

An image was included in the DOM, and an attempt was made to decompress and decode the image from its original format into a bitmap.

These tips might help you to isolate UI responsiveness issues:

Show: