Promptless AI is here soon - Production-ready contextual code. Don't just take our word for it. Know more
Know More

Simplifying Flutter Profiling with Run and Build Modes

No items found.

Nidhi Sorathiya

August 14, 2023

Nidhi Sorathiya

August 14, 2023

Running Flutter in Profile Mode

With the rising popularity of Flutter, understanding how to measure the performance of your Flutter application becomes crucial. Flutter profiling is a process that helps us understand the performance characteristics of our Flutter apps. As Flutter developers, we often need to make sure our apps run smoothly - that they start up quickly, render frames swiftly, and respond to user interactions without delay. To achieve this, we're going to explore how Flutter's powerful profiling tools can help us diagnose and solve performance issues.

When it comes to performance profiling in Flutter, running the app in Profile Mode on a physical device is recommended. This approach gives the most accurate performance characteristics of your app as it's closer to how your users interact with the application in real life.

Importance of Testing on a Physical Device

Running a Flutter application on a physical device removes the performance disparities caused by the limitations or enhancements of simulators and emulators. It's critical to remember that these tools don't accurately emulate the hardware of real devices, leading to misleading performance results.

Reasons for Not Using Simulator or Emulator in Flutter Profiling

Simulators and emulators exist to provide a convenient environment for application development, not for measuring real performance. As developers, we need to understand that the performance experience on a real device can drastically differ from that on an emulator or simulator.

The Differences Between Debug Mode and Profile Mode

Flutter offers developers three modes: Debug Mode, Release Mode, and Profile Mode. However, Debug Mode introduces extra checks like assertions that are absent in the other modes, which can introduce jank or stalls in the app's performance. Hence, it's not ideal for performance measurements.

How to Run Flutter in Profile Mode with VS Code, Android Studio and Through Command Line

To launch your app in profile mode, open your launch.json file in VS Code and edit the flutterMode property as follows:

In Android Studio and IntelliJ, you can use the Run > Profile... menu item.

From the command line, you can also easily start your Flutter app in Profile Mode:

Demystifying the Flutter Build Modes

Gain an edge in your Flutter development by understanding the different build modes that it provides. The mode you choose impacts the app's performance and can consequently affect the user experience.

Simplifying Flutter Profiling with Run and Build Modes
Flutter Build Modes

The Importance of the Profile and Release Modes

The Profile and Release Modes signify the production readiness of your Flutter app. By running apps in Profile Mode, you can identify performance bottlenecks, while Release Mode gives the real-life performance attributes of your app.

Explanation of the Different Build Modes in Flutter

Debug Mode is the first mode, which is great for development and testing, with Hot Reload being one of the key benefits. However, it is not suitable for performance profiling due to the additional checks and non-optimized code execution.

Profile Mode is the next and is similar to Release Mode but with some additional capabilities for profiling and tracing the app's performance. It doesn't have some of the debugging functionalities seen in Debug Mode, making it a great balance for profiling.

Release Mode represents the polished version of the app where all debugging information is stripped out, code is fully optimized, and we have the fast execution required for deployment.

Below is an example of setting the build mode in the Flutter command line:

Leveraging DevTools for Flutter Profiling

Flutter DevTools is a suite of debugging and performance profiling tools, delivered as a web app, which greatly assists us in improving our Flutter app’s performance. With the help of DevTools, we can delve into the intricacies of our Dart code and Flutter widgets to analyze performance issues.

DevTools offers a range of features, like a source-level debugger, a widget inspector, and a suite of additional tools that can efficiently profile the performance of a Flutter application. The use of DevTools provides visibility into how the Dart runtime is managing memory, what the current call stacks are, and many other pieces of information that we can use to optimize our Flutter apps.

Prominent Features of DevTools for Flutter Profiling

Some of the features offered by DevTools include a detailed inspection of all Dart code, analyzing memory usage, viewing all widget rebuilds & repaints, logging diagnostics, and examining all existing widget trees. With these capabilities, we can ensure that our Flutter apps are streamlined and efficient.

Decoding the Performance Overlay in Flutter

One of the most useful tools provided by Flutter for profiling is the performance overlay. This tool graphically presents the performance of your Flutter application, thus allowing you to visually identify areas of your app that need performance optimization.

Simplifying Flutter Profiling with Run and Build Modes
Performance Overlay in Flutter

Flutter's Performance Overlay is a graphical tool that displays statistics related to the current performance of your Flutter application, specifically in terms of the UI and raster threads. This allows developers to get a quick overview of the overall performance and spot potential areas needing optimization.

Reading the UI and Raster Thread Graphs in the Overlay

The Performance Overlay displays two graphs - one for the UI (User Interface) thread and one for the Raster thread. These graphs show where time is spent during each frame rendered by the Flutter engine. The vertical green bars represent the current frame.

Understanding the Meanings of Colored Bars on the Graphs

In the Performance Overlay graphs, each bar signifies a rendered frame. When the graph goes over the white lines (denoting 16ms increments), this connotes that your app is lagging behind the recommended 60 frames per second.

The Thread Structure in Flutter

Despite your direct interaction primarily with UI thread during the development process, Flutter app's performance greatly depends on the efficiency of the various threads it uses. Understanding these threads can provide additional insights into the app's performance.

Simplifying Flutter Profiling with Run and Build Modes
Thread Structure in Flutter

Flutter makes use of multiple threads for executing different tasks to ensure smooth and fast execution. While the Dart code runs on the UI thread, other threads are in play in the background to maintain high performance.

Roles of Platform, UI, Raster and I/O Threads in Flutter Profiling

Here are the roles of different threads in Flutter:

  1. Platform Thread: This is the main thread of the platform. All plugin code runs here. This thread does not show up in the performance overlay.
  2. UI Thread: Dart code runs here. The UI thread generates layer trees and sends them to the raster thread for rendering. This shows in the bottom row of the performance overlay.
  3. Raster Thread (previously GPU Thread): This thread is responsible for rendering the layer tree onto the screen by leveraging GPU resources. Dart developers don't have direct access to this thread, but actions on the UI thread can impact its performance.
  4. I/O Thread: This performs expensive tasks, primarily I/O, that would otherwise block either the UI or raster threads.

By understanding the role of each thread, we can pinpoint the cause of performance issues in our Flutter apps.

Displaying the Performance Overlay in Flutter

Getting a live visual representation of your app's performance can greatly aid in turning the tide on performance issues. By using the Performance Overlay, you can tackle performance issues one frame at a time.

Enable Performance Overlay: To toggle the display of the performance overlay, you can use the Flutter inspector, command line, or even enable it programmatically.

Using Flutter Inspector and Command Line for Overlay Display:
  1. With the Flutter inspector in DevTools, simply click the Performance Overlay button to toggle the overlay on your running app.
  2. From the command line, use the 'P' key to toggle the performance overlay.

This code example shows you how to enable performance overlay programmatically. It can sometimes be more convenient to have the code handle enabling the performance overlay, especially when working on a larger codebase or team.

Diagnosing UI and GPU Problems

Flutter’s performance overlay tool facilitates diagnosing performance issues in your Flutter app. By identifying issues in UI and GPU graphs, performance can be optimized effectively.

Identifying UI Thread-Based Problems

The UI graph in the performance overlay highlights the performance metrics related to your Dart code execution. If you see any red bar in the UI graph, it may indicate that some of your Dart code is computationally expensive. In such a scenario, it's recommended to profile your Dart code to identify the potential cause of the performance issue.

Analyzing Graphical Rendering Difficulties in the GPU thread

Performance issues can also stem from the raster thread (previously known as the GPU thread). A red bar in the raster thread on the performance overlay may indicate that the constructed scene is expensive to render, usually due to complex layer compositions.

Viable Solutions to Known Performance Issues

By documenting and analysing the common performance issues and their solutions, Flutter has made it easier for us developers to optimize applications. Here we talk about a few practical approaches to solve such problems.

Simplifying Flutter Profiling with Run and Build Modes
Solutions to Performance Issues

Optimizing Layer Construction and Rendering

In cases where the UI graph is clean but the raster graph shows red bars, it implies your scenes may be easy to construct but expensive to render. Such workloads usually involve unnecessary saveLayer calls, complex clippings or shadows, or intersecting positive opacities with multiple objects.

Utilizing Slow Animations Feature for Analysis

If you identify the cause of the slowness to be an animation, Flutter offers a Slow Animations button that you can use to slow down animations by 5x, making it easier to analyze the performance.

In this example, we have a fading animation on an icon. If we suspect this animation could be causing a performance issue, using the slow animations feature can let us conduct a more detailed analysis.

Analyzing Offscreen Layers and Non-cached Images

The efficiency of Flutter apps can also be influenced by offscreen layers and non-cached images. Let's learn how we can diagnose these issues.

Impact of SaveLayer Method on Performance: The saveLayer method is one of the most expensive operations in the Flutter framework. It's especially useful when applying post-processing effects to the scene, but it can significantly slow down your app if not used judiciously.

Techniques to Check SaveLayer Usage: You can check whether your scene uses saveLayer with the PerformanceOverlayLayer.checkerboardOffscreenLayers switch. Once the switch is enabled, run the app and check for any flickering boxes outlining images or groups of objects which indicate usage of saveLayer.

The Role of RepaintBoundary in Image Caching

Caching plays an essential part in ensuring smooth performance, especially when dealing with images. RepaintBoundary helps in effective image caching in Flutter.

Importance of RepaintBoundary in Flutter Profiling: When a layout or painting change happens, the framework recursively reapplies these operations to the affected parts of the tree. A RepaintBoundary widget can be inserted at various points in the tree to prevent unnecessary repaints, which effectively saves the CPU and GPU time.

Situations When RepaintBoundary is Useful:

This example shows an image with an icon circling around when tapped. Here the RepaintBoundary prevents the entire tree from being repaint upon updating the position of the icon.

Application of Widget Rebuild Profiler

One of the easiest ways to boost the performance of your app is to limit the number of unnecessary widget rebuilds. The widget rebuild profiler helps you detect and tackle such performance problems.

Simplifying Flutter Profiling with Run and Build Modes
Widget Rebuild Profiler

A widget rebuild is triggered every time you call setState. Some widgets rebuild more frequently than others, and these are the ones that can contribute to the "jank" in your app.

Importance of Widget Rebuild Profiler: The widget rebuild profiler is a tool that can assist you in identifying which widgets in your app are being rebuilt, and how often. This can be invaluable information when attempting to optimize your app's performance, as minimizing unnecessary widget rebuilds can have a significant impact on your app's speed.

Usage and Benefits of Widget Rebuild Profiler: You can find the count of rebuild widgets by using the Flutter plugin for Android Studio and IntelliJ. By reducing the count of widget rebuilds, you will be able to increase the frame rendering rate and reduce time complexity leading to improved performance.

Benchmarking in Flutter

Benchmarking is a helpful way of measuring the performance of your code over time. It is especially useful when you want to make sure that performance improvements or regressions don't go unnoticed.

Defining and Importance of Benchmarking: Benchmarking involves running a set of tests or procedures to assess the relative performance of your app, and identify potential areas for improvement. This process is critical as it provides quantifiable metrics that give you a clear understanding of where your application stands in terms of performance.

How to Create Benchmark Tests using Flutter Driver Library: Flutter Driver is a testing library that enables developers to write end-to-end integration tests and automate actions on the app. Using this, you can create and execute benchmark tests that can measure the performance of your app in terms of startup time, memory efficiency, etc.

In this simple example, we are running a benchmark test on 'MyApp' and generating a summary file that contains detailed insights about the performance.

Nurturing High-Performing Flutter Apps

As we cross the finish line of our detailed exploration of Flutter Profiling, let's pause to take stock of what we've learned and how we can implement these lessons to efficiently optimize our Flutter applications.

Through the lenses of Flutter run profile, Flutter build profile, and Flutter profile page, we've unlocked the diverse aspects of optimizing the performance of a Flutter application. From understanding the significance of Profile Mode, the magic of Flutter's multi-threading system, to actionable solutions for common performance issues and the power of benchmarking, Pandora's box of Flutter’s performance profiling has been laid bare for us.

Accelerating the performance of your Flutter application can seem a daunting task at first glance. But armed with the understanding of Flutter's profiling tools and techniques, you can comfortably rise to meet that challenge. Remember, achieving a smooth, efficient application is an iterative process, a continual dance of diagnosing problems and applying optimisations. But with the knowledge you now possess, you're well-equipped to manage this dance with grace and assurance.

Frequently asked questions

Q: What is the difference between debug and profile mode in Flutter?

Debug mode enables additional checks (such as asserts) that don't run in profile or release mode, and these checks can slow down the app. Debug mode also compiles Dart code "just in time" (JIT) during the app runtime, which can cause pausing for JIT compilation, leading to performance hiccups or jank. On the other hand, profile mode is closer to release mode, but with just enough additional functionality to allow debugging of performance problems. It provides tracing information, which aids in diagnosing the cause of any slowdowns in your application.

Q: What is Flutter not good for?

While Flutter is a strong framework for mobile application development, it may have limitations for apps that require substantial interaction with the device operating system, such as apps that need significant background processing, inter-app communication, or are heavily reliant on multiple native APIs not yet available in Flutter.

Q: How do I run profile mode in Flutter?

You can run your Flutter app in profile mode using various methods: In VS Code, by updating your launch.json file; In Android Studio and IntelliJ, by selecting Run > Flutter Run main.dart in Profile Mode from the menu; and from the command line, using the --profile flag with the flutter run command.

Q: What is the difference between Flutter build and run?

'flutter run' compiles your Dart code and starts up your Flutter application on an emulator, simulator, or hardware device. It's primarily used during the development phase. flutter build, on the other hand, compiles Dart code to a standalone app, ready for distribution on PlayStore or AppStore. It is used to generate a release build for your Flutter application.

Q: What is profile mode and when do you use it?

Profile mode is one of the three modes in Flutter apart from Debug and Release modes. It compiles your application almost identically to Release Mode, but with just enough debugging ability to allow profiling of performance issues. Profile mode is used when you want to analyze your app performance as it removes additional checks and slows downing components present in Debug mode and gives an environment closer to Release Mode. This helps in getting a more accurate picture of the actual performance of your app.

Frequently asked questions

No items found.