Peak Flutter performance, or How to bring your app to 60 fps

Grzegorz Trochimiuk
Deviniti Technology-Driven Blog
4 min readAug 27, 2020

Flutter does a lot to make sure every app can run at smooth 60 fps and yet not every app does. In this article, we’ll go through several simple tips that will help you bring your apps to peak performance.

Build cost

One of the simplest mistakes that affect performance is putting too much code in the build method of a widget. It can be invoked frequently when ancestor widgets rebuild, so we must make sure we control its cost. Everything that isn’t absolutely necessary to define your widget hierarchy needs to be calculated outside of the build method.

Another thing to avoid is making single widgets with overly large build methods. There are many benefits to splitting up your code and using a lot of small widgets — like readability and reusability — and performance is one of them. You should split your widgets based on their function but you also have to keep in mind how they will change — why rebuild an entire tree of widgets if you can only rebuild a subtree?

Lazy lists

The next thing that you should always opt-in for when given a chance is lazy lists and grids. By using the builder constructor of ListView and GridView widgets, you allow Flutter to make a lot of optimizations for you. It will make sure that only the children that are actually visible are being built, which will improve performance by a lot!

Expensive widgets

There are a lot of powerful widgets in Flutter, but that power comes at a cost, so you should always consider and test performance before you decide to use them. Fortunately, they are well documented, so if you read the documentation of a widget before you use it (like you should) you will be aware of possible risks and alternatives. Examples of expensive widgets include:

IntrinsicHeight and IntrinsicWidth

A widget that allows its child to size itself automagically to fit content might seem like a perfect solution to a lot of layout issues, but there are often alternate solutions that are more efficient. These widgets are definitely there to use them, but you should always think your layout through before you snap them on top of your widget tree.

Opacity

A lot of good looking designs incorporate semi-transparent elements. The Opacity widget is great because it is so simple in use. But in some cases, you should probably use a more efficient alternative:

  • When animating opacity, always use widgets like AnimatedOpacity or FadeInImage instead.
  • When applying opacity to a color or an image, it is more efficient to do so without using the widget.

You can just use:

Container(color: Color.fromRGBO(255, 0, 0, 0.5))

instead of:

Opacity(opacity: 0.5, child: Container(color: Colors.red))

And to apply opacity to an image, you can just use a color with a correct blend mode:

Image.network(
imageUrl,
color: Color.fromRGBO(255, 255, 255, 0.5),
colorBlendMode: BlendMode.modulate
)

- BackdropFilter

Applying effects such as blur to all content drawn below a certain widget can be expensive, so make sure to test performance if you use it.

Animations

Everybody loves animations. Even a subtle animation here and there adds a lot to user experience and makes your app seem more polished — but only if the app still runs smoothly. To ensure 60 fps you should only update what’s needed in your AnimatedBuilder. Use the child property to define all the elements that do not need to change during animation instead of defining them in the builder method. That way the subtree that does not depend on the animation will only be built once and not on every animation tick. Another thing to avoid when implementing animations is clipping images — in most cases, you can pre-clip the image before animating it.

Const keyword

By using const constructors when possible, you allow Flutter to build the widgets that won’t change only once and never rebuild them. It’s a small performance improvement that adds up in larger apps. The best thing is that you can use linter to let you know that you should use a const constructor in a specific place in your code and keep your development process fast. If you don’t know how to set up linter, check out this article.

Conclusion

As you can see you can improve performance in your app just by keeping these couple of things in mind during the development. Hopefully, you learned something new.

Deviniti is your guide to the universe of digital transformation and enterprise software. Check out who we are and what we can do on our website.

If you want to learn more Flutter tips and tricks, make sure to check out other articles available on Deviniti Technology-Driven Blog:

--

--