Reducing Flutter App size
Tags: flutter, application, optimisation, production
Published: 2020-08-16 10:30:06


Whenever we build an app, the app size optimisation is always a difficult part. Even in 4G and modern smartphone era people prefer smaller apps and the smaller apps are more likely to be downloaded. Unlimited internet is no for everybody. ***More than 337 million smartphone users with limited data plans**.* So after all coding part we do optimisation and try to reduce the app size. In the terms of optimisation *each and every bytes matters*. 

> 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

Ref: [Article](https://medium.com/pixplicity/size-matters-how-your-app-size-is-costing-you-customers-6121d6db74e) 

There are many good coding practice 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 practice 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.

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

Also compress PNG and JPEG files before uploading to your storage. The free online resource to compress PNG image is [https://compresspng.com/](https://compresspng.com/). 

### 2. **Use Google Fonts**

Initially flutter app can have custom font styles only assessing the font file from assets folder. Similar to images these fonts will also increase app size. The best solution is using `google_fonts` 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 variation with your project.

```dart
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.17, 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 desing you might need to use other icons. In that case **use .svg format icon** so you doesn’t need to worry about different device DPI’s and this also helps in reducing apk size.

![App size reduce use SVG](https://dev-to-uploads.s3.amazonaws.com/i/bvaz7qi9rdnoob4fri3q.jpg)

### 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.

![Flutter App Size Reduce](https://dev-to-uploads.s3.amazonaws.com/i/p6v9yqz5n2qmsxtj9wnj.png)

But some of the store 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.

```bash
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.

```dart
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](https://developer.android.com/studio/build/shrink-code).

### 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.

For more blogs on Flutter visit [Smazee](https://smazee.com/blog)