Size matters: Reducing Flutter App size best practices

Suryadevsingh
6 min readSep 12, 2020

--

2.6 million apps in the Google Play store today — no wonder convincing a user to install your app has never been more difficult. As if it wasn’t difficult enough already, plenty of your users have seen this dialogue — probably multiple times — as well:

Let’s assume that you have a retail store and you ship an app to make the shopping experience smoother and quicker. You’ve added AR filters and applied Machine Learning to figure out your user's preferences and to tailor the experience. In other words, you’ve made a freakin’ awesome shopping app! Wow! It even supports Android 4.4 and 8 different languages. Good for you!

Now, how many people (especially from those that have a problem with the device storage space) do you think that they are going to download it if they see the following message?

“more than 337 million smartphone users with limited data plans”

So after all coding part, we do optimization and try to reduce the app size. In terms of optimization each and every bytes matter.

The download completion rate of an app with an APK size of around 10MB will be ~30% higher than an app with an APK size of 100MB

There are many good coding practices and building a stable architecture will help the app to perform better. We can talk about it in detail in another article. Apart from that, there are some common methods and practices that you can implement in your app to make it better.

7 Flutter app Performance Tips

1. Image Asset

In Flutter people uses images from assets folder to display in the app. In development mode, this will be useful as the images are loaded faster. But when you bundle the app these images adds more weight to the app. The solution is of using network images. Upload the images in permanent storage path like AWS or in your website server and use the link to that image in your code.

Image.network( 'https://picsum.photos/250?image=9',
)

Also, compress PNG and JPEG files before uploading them to your storage. The free online resource to compress the PNG image is https://compresspng.com/.

2. Use Google Fonts

Initially, the flutter app can have custom font styles only assessing the font file from the assets folder. Similar to images these fonts will also increase app size. The best solution is using google_fonts a plugin. This plugin will dynamically download font when it is used and it will download it in a specific style and language so that you don’t need to ship all of the variations with your project.

Text(
'This is Google Fonts',
style: GoogleFonts.lato(
textStyle: Theme.of(context).textTheme.display1,
fontSize: 48,
fontWeight: FontWeight.w700,
fontStyle: FontStyle.italic,
),
),

3. Icons

It is recommended to use from Material Icons or Cupertino Icons class. From Flutter 1.20, you can add --tree-shake-icons option to flutter build command, to remove all of the not used icons from the bundle. This will potentially save the size of your app.

But in many situations due to modern design you might need to use other icons. In that case use .svg format icon so you don’t need to worry about different device DPI’s and this also helps in reducing apk size.

4. Dynamic App Delivery

We could build an app bundle if we are uploading to playstore or we could split the apk per abi which splits the apk to x64 and x86 bit code. By using appbundle Google Play’s new app serving model, called Dynamic Delivery, uses your app bundle to generate and serve optimized APKs for each user’s device configuration, so they download only the code and resources they need to run your app.

But some of the stores like Amazon App store still doesn’t support appbundle in that case you can use --split-per-abi command which will give you three version of apks.

On average, apps published with app bundles are 20% smaller in size.

flutter build appbundle
// or use
flutter build apk --split-per-abi

5. Cache

Using cache will not help in reducing app size but it will make the app to load faster and hence improving the app performance. All frequently used images like profile pic, bg picture using cached_network_image plugin.

The cached_network_image package allows you to use any widget as a placeholder. In this example, display a spinner while the image loads.

CachedNetworkImage(
imageUrl: "http://via.placeholder.com/200x150",
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
colorFilter:
ColorFilter.mode(Colors.red, BlendMode.colorBurn)),
),
),
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),

6. Proguard

Proguard is a java program optimizer. It is not specific to Flutter. It optimizes your code in ways that don’t change the functionality but change the representation to make it more compact. It obfuscates name of types, fields, methods where the original name doesn’t matter such that long names are replaced with short strings like a and b for efficiency. Packages and classes may have a long name but should not hinder efficiency. It also removes unused java code from dependencies.

You have two default proguard file you can apply.

  • proguard-android-optimize.txt — progurard configuration
  • proguard-android.txt

We used proguard-android-optimize.txt as the default proguard configuration. You can add you custom proguard configurations in proguard-rules.pro file in your /app directory.

release {
//Enable the proguard
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), "proguard-rules.pro"

//Other parameters
debuggable false
jniDebuggable false
renderscriptDebuggable false
signingConfig playStoreConfig //Add your own signing config
pseudoLocalesEnabled false
zipAlignEnabled true
}

By setting minifyEnabled to true, the proguard will remove all the unused methods, instructions and slim down the classes.dex file.By enabling the proguard in every module of our project we can we are able to reduce the classes.dex file size almost by 50%.

Learn more about proguard here.

7. Use Specific Libraries

Calling packages not needed or used in our pubspec.yaml file should be avoided. Once done building your app, you should check your pubspec.yaml and remove libraries/packages which is/are not used. Also remove all the unused assets from pubspec.yaml.

Also in certain situations due to unavailability of some features me might used some 3rd party plugins. But in some future update Flutter might have resolved it and had a built-in solution. In those case using default Flutter solution is a good practice than using the 3rd party plugins.

Need your support

Follow me on Linkedin, GitHub, and Medium.

You can connect me to suryadevsingh24032000@gmail.com .

--

--

Suryadevsingh
Suryadevsingh

Written by Suryadevsingh

Just Converting Imagination into Reality.

No responses yet