Monitor Performance of your Flutter App with DevTools: Overview

Nitin PoojaryNitin Poojary
5 min read

Why Performance monitoring is important

Performance monitoring helps you check if your app is running at 60 fps and can spot any UI problems that cause lag on slow or old devices. By finding performance issues early in development, we can stop them from reaching production. If your app isn't running at 60 fps or has jank, it can negatively affect the user experience during animations or when scrolling through content.

Running the app in Profile mode

Running the app in Profile mode allows us to use the app as in release mode, with some extras. For example, we can attach DevTools to the running app and monitor its performance. Performance debugging for Flutter applications should be done on a physical Android or iOS device, with your Flutter application running in profile mode. Using debug mode or running apps on simulators or emulators usually does not reflect the final behavior of release mode builds. Consider checking performance on the slowest device that your users might reasonably use.

To run the app in Profile mode, open the terminal and enter the command below:

flutter run --profile

To use DevTools from VS Code, open your main.dart file and click on Profile above the main function, as shown in the image below.

Displaying Performance Overlay in the App

Before diving into DevTools, let's display an overlay directly in our app using showPerformanceOverlay.

 @override
  Widget build(BuildContext context) {
    return MaterialApp(
      showPerformanceOverlay: true, // add this line
      title: 'Material App',
      home: HomeView(),
    );
  }

Now run your app in Profile mode. You should see an overlay similar to the one displayed below.

Let's take a look at what's happening here. We can see two histogram graphs representing two threads: the raster thread and the UI thread. The lower graph shows the UI thread, where all of our Dart code runs. Above it, there is a graph for the raster thread, which takes instructions from the UI thread and translates them into something that can be sent to the graphics card. For more details, refer to the Flutter docs.

Use DevTools to Monitor Performance

First, run your app in Profile mode. If you are using VS Code, you can open DevTools by clicking the DevTools button in the status bar at the bottom. I prefer using DevTools in a browser, so to open it, press Ctrl+Shift+P, select Open DevTools, and then choose Open DevTools in Web Browser. Go to the performance tab, and you should see a screen similar to the one below.

Let's go through each component one by one, starting with the histogram graph.

Flutter frames

These are the Flutter frames shown in a histogram graph format. The x-axis represents the time taken to build each frame in milliseconds, and the y-axis shows the number of frames built. Each frame is represented by a pair of histograms: the left one for the UI thread and the right one for the raster thread. This is similar to what we saw in the overlay on the app.

On the right side of the graph, we can see the meaning of the colors used in the histogram. If any frame of our app has jank, it will be highlighted in orange or red. You can also see the number of janked frames in the Performance tab.

By default, when you run the app in Profile mode and go to the Performance tab, it starts capturing the frames and draws the graph automatically. However, you can control this with the pause and play buttons, as shown in the image above.

Now, let's discuss the components located above the graph on the right side of the screen.

Performance Overlay

This is a toggle button to enable or disable the Performance Overlay. Turning on the Performance Overlay is similar to adding showPerformanceOverlay in our code. In both cases, we see the overlay graph on the screen where the app is running.

Enhance Tracing

Enhance Tracing tool helps us to view detailed timeline event charts. This comes with a cost, as indicated by the red text in the image stating, "frame times may be negatively affected," and for lower-end devices, it's always affected.

We will explore these topics in more detail in future blogs.

Frame Analysis

Tap on any of the frames to view the data as shown below:

Here, we can see the number of the frame we tapped on. Since there's no jank, suggestions are not available. Below that, we can see the time taken for the build, layout, and paint phases of the UI, as well as the time taken by the raster thread. The count widget builds feature is available in debug mode, but we won't cover that here.

Rebuild Stats

Only available in debug mode to check the count of every widget that was built.

Timeline Events

To display the timeline events, DevTools uses Perfetto, a production-grade, open-source stack for performance instrumentation and trace analysis developed by Google. You can use the WASD keys to zoom in, move left, zoom out, and move right, respectively. For other shortcuts that can be used in Perfetto, press ?.

The timeline events chart shows all event tracing from your application. Time line events can be sent using Timeline and TimelineTask APIs. The Flutter framework emits timeline events as it works to build frames, draw scenes, and track other activity such as HTTP request timings and garbage collection. To update the timeline with new events from your application, click the refresh button located in the upper right corner of the tab controls.

Scroll down to the Process section to view the UI thread and all the events emitted on it. As you can see, the data here is not very helpful. We can see the build, layout, and paint functions being called, but not much else. This can be improved with Enhance Tracing options. We'll explore that in the next blog.

1
Subscribe to my newsletter

Read articles from Nitin Poojary directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Nitin Poojary
Nitin Poojary