When you have Flutter app performance problems, try Profile Mode

Today I learned that for several reasons, Flutter Debug mode may be significantly slower than Production mode. As just one reason, Debug mode is compiled using JIT while Production mode uses AOT. You can read more about the reasons on the Flutter UI Performance page.

A very important note on that page is that if you’re using a real hardware device (as opposed to an emulator), you can run your code in Profile mode like this:

flutter run --profile

Per that performance page:

“Flutter’s profile mode compiles and launches your application almost identically to release mode, but with just enough additional functionality to allow debugging performance problems.”

You can read more about profile mode on the Flutter build modes page, but for today, if you’re concerned about the performance of your Flutter application, give profile mode a try on a physical device and see if your Flutter performance problems go away.

The Flutter “Skipped frames, doing too much work on its main thread” message

I learned more about this after I became worried about the performance of my app, both from what I was seeing in the emulator and from Flutter messages like this:

I/Choreographer( 9147): Skipped 32 frames!
The application may be doing too much work on its main thread.

I know that Flutter shoots for at least 60 frames/second, so this was a concern.

Why you should run your Flutter app on a real device

That Flutter performance page states that there are at least three reasons you should test the performance of your Flutter apps on real devices using profile mode (the following text is almost word for word from their page):

  • Simulator and emulator hardware isn’t the same as real devices, so performance may be worse (or better) in different areas than real devices
  • Flutter Debug mode enables additional checks that don’t run in profile or release builds
  • Very importantly, debug mode executes your Dart code in a different way than release mode. Debug mode compiles the code “just in time” (JIT) as the app runs, but profile and release builds are pre-compiled to native instructions using “ahead of time” (AOT) compilation — before the app is loaded onto the device. Using JIT can cause the app to pause during JIT compilation.

So again, if you’re concerned about the performance of your Flutter app, try testing it in Profile Mode on a real hardware device.