Take your Flutter App performance to next level: Part - 2

Cavin Macwan
7Span
Published in
6 min readDec 19, 2022

So here’s the 2nd part of my previous series on increasing the performance of your Flutter app.

If you haven’t read the first part yet, you can click on the link below to read it

So without further a do, let’s get started 😉

1. Use ListView.builder/GridView.builder when you want to display a large number of data

To understand this more properly, consider the following code :

Simple ListView
  • In the above code, you can see we are displaying 4 items in ListTile. You might be thinking it’s not so new at all we already know this, what’s new in this?
  • Now consider the code below :
ListView.builder example
  • In this example, we’re using ListView.builder instead of a simple ListView, and it technically renders the same things on the screen. But now let’s talk about the difference between those two.
  • When we use ListView/GridView or wrap a Column in SingleChildScrollView then what it does basically renders it’s all of the children when we open that screen. If the data is small then it won’t make much big difference but if we have thousands of data then our app will start to stutter or worse it will crash
  • But then what about ListView.builder()?
  • ListView.builder() / GridView.builder() only renders the data which is visible on the screen. So you can have thousands and thousands of data but it will only render the data which we are seeing on a screen at a particular time, therefore it won’t try to load every data in its memory which is a lot more performance efficient.

Bonus tip :

Suppose you are animating a list of items in ListView.builder()/GridView.builder() and you want to only animate it the first time the user scrolls or something like that. In those scenarios, you can use addAutomaticKeepAlives: true property. But if you only apply those properties then there are some chances that it will not still work. You can follow the steps to achieve it :

  • First, add the addAutomaticKeepAlives: true property in ListView.builder()
  • Now, extend your state class AutomaticKeepAliveClientMixin and set wantKeepAlive it to true and add super.build(context) in your build method. Here’s the code

Now this will keep the child alive even after we scroll it.

2. Use for/while loop instead of foreach

In dart language, there are so many types of loops to iterate through the list such as simple for loop, while loop, forEach and for in loop. But you will be surprised to know that they also have different types of performance!

  • Below is the graph comparing the speed of each loop
Time comparison for every loop in dart
  • Caching the length of the list involves setting the length of the list we will be looping through to a variable before looping. Here is an example of a while loop with an uncached length
  • And below is an example of a while loop with cached length:
while loop with cached length
  • When we cache the length of a list before looping, the length of the list is calculated only once and not recalculated on each iteration.
  • But when we don’t cache the length, then it’s calculated per iteration. For lists with a large number of elements, this should have significant performance gains.
  • Now you might be thinking that how did this graph come from and how do we measure the speed of each loop?
  • There’s a package on pub.dev called benchmark_harness that is used for measuring the speed.
  • If you want to learn more about these comparisons, you can read this article :

3. By using the RepaintBoundary widget

  • First, take a look at the below GIF
Without enabling the repaint boundary widget ex.1
  • In example 1, you can see that border colors are changing, which represents that the whole UI is rebuilding. But, one thing is more interesting in it, the StableWidget is still repainted every time even though it is not changing at all
  • Therefore we can conclude that it is building unnecessary parts each time, so the solution is we can tell the framework explicitly to not paint those widgets again which are not changing

We can do this by wrapping the widget which is changing inside the RepaintBoundary widget, it will tell the framework explicitly not to paint anything outside it.

Below is the example when you enable RepaintBoundary widget.

  • But you might be thinking cavin how can I confirm that this is the only widget which is changing and causing this painting to every child, the answer is the below code snippet

You can put debugRepaintRainbowEnabled=true before calling the runApp() and it will show the border on the App. And you will be able to differentiate between the widgets that are changing and the widgets which aren’t.

  • Below is the link to dartpad example which is officially provided by Google

4. Use itemExtent in ListView for long Lists

Imagine a scenario where you have integrated a large number of lists in your listview and you want to jump directly to the last element from the first element or vice versa. Now if you will notice, you can see that while going from 1st element to the last element, it will lag a bit

  • You can try the below code snippet to confirm it:
  • Now, if you set itemExtent: 200 in the ListView of the above code snippet, it will start running smoothly again. But exactly does item extent do?
  • Specifying an itemExtent is more efficient than letting the children determine their own extent because the scrolling machinery can make use of the foreknowledge of the children’s extent to save work, for example when the scroll position changes drastically. (From the official docs)

So these were all the tips from which you can increase the performance of your app to the next level.

Thanks for reading this article ❤️

Keep clapping 👏 (you can appreciate it by clapping 50 times)

If you face any issues with implementing any of these tips, you can reach out to me, I’ll be happy to help you! Also, you can share your thoughts on this article with me in the Comments / LinkedIn

Connect with me on Twitter :

--

--

Cavin Macwan
7Span
Writer for

Passionate mobile developer. One thing I like more than learning new things: sharing them #FlutterDev| Developer @7Span | Contributor