Boost Your Flutter App Performance With These 6 Tips

Introduction Link to heading

Get better scrolling and animations, less memory consumption, and more execution speed. Boost your Flutter app performance with these 6 tips. And if you want more, I have a free ebook with additional tips for you at the end!

Here are some easy-to-use best practices for Flutter apps when it’s all about performance. Use them if you notice any problems but don’t optimize prematurely. Flutter apps are fast by default and you won’t have any trouble usually. Here is how you can boost your Flutter app performance with these 6 tips.

Also, make sure to download my free ebook about Flutter performance tips. You can find the link at the end of this article.

Prefer StatelessWidget over StatefulWidget Link to heading

A StatelessWidget is faster than a StatefulWidget because it doesn’t need to manage state as the name implies. That’s why you should prefer it if possible. Choose a StatefulWidget when…

▶ you need a preparation function with initState()
▶ you need to dispose of resources with dispose()
▶ you need to trigger a widget rebuild with setState()
▶ your widget has changing variables (non-final) In all other situations, you should prefer a StatelessWidget.

⛔ Bad example

Dart

import 'package:flutter/widgets.dart';

class MyWidget extends StatefulWidget {
	final String header;
	final String subheader;

	const MyWidget({Key? key, required this.header, required this.subheader}): super(key: key);

	@override
	State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
	@override
	Widget build(BuildContext context) {
		return Column(children: [Text(widget.header), Text(widget.subheader)]);
	}
}

✅ Good example

Dart

import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
	final String header;
	final String subheader;

	const MyWidget({Key? key, required this.header, required this.subheader}): super(key: key);
	
	@override
	Widget build(BuildContext context) {
		return Column(children: [Text(header), Text(subheader)]);
	}
}

Use builder constructors on long lists or grids Link to heading

When dealing with lists or grids with many items, it is recommended to use the builder constructors. Their advantage is that only visible elements are rendered. So if your list or grid is bigger than one device screen, you should choose this approach. For smaller lists and grids, the default constructors can also be used. This applies to all types of lists and grids like ListView, ReorderableListView, or GridView. Always check for a builder constructor and use it if possible.

✅ Good example

Dart

final List<int> _listItems = <int>[1, 2, 3, 4, 5, 6, 7, 8, 9];

@override
Widget build(BuildContext context) {
	return ListView.builder(
			itemCount: _listItems.length,
			itemBuilder: (context, index) {
		var item = _listItems[index];
		return SizedBox(
			height: 300, child: Center(child: Text(item.toString())));
		}
	);
}

Don’t use OpacityWidget Link to heading

The Opacity widget can cause performance issues when used with animations because all child widgets of the Opacity widget will also be rebuilt in every new frame. It is better to use AnimatedOpacity in this case. If you want to fade in an image, use the FadeInImage widget. If you want to have a color with opacity, draw a color with opacity.

⛔ Bad example

Dart

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

✅ Good example

Dart

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

Precache images and icons Link to heading

Flutter contains a function precacheImage() which can be used to reduce the loading time of images and icons. You can use it in the initState() or didChangeDependencies() methods to speed up image display, for example.

Dart

const List<CatImage> images = [
	CatImage(width: 150, height: 150, caption: 'Watch out'),
	CatImage(width: 150, height: 160, caption: 'Hmm'),
	CatImage(width: 160, height: 150, caption: 'Whats up'),
	CatImage(width: 140, height: 150, caption: 'Miaoo'),
	CatImage(width: 130, height: 150, caption: 'Hey'),
	CatImage(width: 155, height: 150, caption: 'Hello'),
];

@override
void didChangeDependencies() {
	super.didChangeDependencies();
	for (CatImage image in images) {
		precacheImage(NetworkImage(image.url), context);
	}
}

Reduce memory consumption of ListView Link to heading

A ListView has two properties (addRepaintBoundary and addAutomaticKeepAlives) that can lead to a high memory consumption in certain cases. They tell the ListView to not dispose of items which are not visible on the screen at the moment. In terms of performance, this is good because scrolling is fast. But the invisible items still occupy memory space. If you have a long list of images, this can lead to a problem. The solution is to set the mentioned properties to false (they are set to true by default).

Dart

ListView.builder(
	addAutomaticKeepAlives: false,
	addRepaintBoundaries: false,
	…
);

Always use keys Link to heading

Every widget has a key constructor parameter and creates an element in the widget tree. A key allows us to reuse an element instead of creating a new one. You can either use ValueKeys or GlobalKeys. GlobalKeys can be tricky because there can never be multiple widgets with the same key in the widget tree. ValueKeys on the other hand will lead to bloaty code as you need to define them for each widget.

💡 Tip

Do you want more tips? Check out my free ebook!

Conclusion Link to heading

In this article, you learned how you can boost your Flutter app performance with these 6 tips.

A comparison of 6 JsonToDart tools for Flutter/Dart developers Link to heading

Instead of writing code yourself, you can always use generators to create Dart model classes from JSON. Here are the results of my evaluation of some free tools for you.

How to organize your Flutter app assets, styles, colors, images Link to heading

A growing app has a lot of resources included that are used in various places. With this approach, you’ll know where to put things and how to reference them.

Building a simple text translation app with Flutter and Firebase Link to heading

With Firebase Extensions you can build a simple text translation app that does most of the work for you.