Pushing Flutter to the Limit: The Ultimate Guide to Reducing Flutter App Size

Anuj Kumar Pandey
7 min readSep 10, 2023

--

Whether you’re developing a new Flutter app or looking to optimise an existing one, the insights shared in this article will equip you with the knowledge to make informed decisions about app size reduction.

App size is important for applications. It has two parts:

Download Size: The size of the app on the play store/when downloading/when installing.

Install Size: What happens when you download the app, unpack it, compile it, and optimise it. This significantly expands the application and can be two, three, or even four times the size of the install.

So, when a user goes to install an app say on play store, he sees the loading bar and then the actual app size. The larger the app, the greater the chances of a failed/cancelled download. As developers, we want to get the app size small so that we get as much distribution for our app as possible.

As larger the app the more memory it takes and more time it takes for downloading. And user may uninstall or cut the download progress because of waiting. So here are few tips and guides to help you out.

So lets start it!!

1. Use SVG or WEBP for icons and vector images

Consider using SVG (Scalable Vector Graphics) files instead of PNGs or JPEGs. SVGs are vector-based, so they occupy less space and don’t lose quality when scaled. Or, you can use WEBP instead of JPG/PNG. It’s like JPG/PNG but it’s ~25% smaller in size.

Source

2. 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),
),

3. Shake Your Icons

Flutter has the functionality to shake out unused icons from Material, Cupertino, FontAwesome, etc. fonts.

Source

For Android
It would be setting the tree-shake-icons property in the gradle.properties

For iOS
If you’re building from Xcode, you can set the TREE_SHAKE_ICONS environment variable

4. Whatever you use, COMPRESS it!

Everybody knows they can and should JPG/PNG compress but how many people know you can also compress SVG and WEBP images?

You can use tools such as pngquant, zopflipng, or pngcrush. All these tools you can use to reduce image size without compromising its quality.

Moreover, to compress JPEG images, you can utilize other tools such as guetzli and packJPG. The free online resource to compress the PNG image is https://compresspng.com/.

Or,

For example lang files:

final String response = await rootBundle.loadString('assets/en_us.json'); 
List<int> original = utf8.encode(response);
List<int> compressed = gzip.encode(original);
List<int> decompress = gzip.decode(compressed);
final enUS = utf8.decode(decompress);

5. Use Proguard Rules

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 also removes unused java code from dependencies.

Add to the file android/app/build.gradle

android { 
buildTypes {
getByName("release") {
// Enables code shrinking, obfuscation, and optimization minifyEnabled = true
// Enables resource shrinking
shrinkResources = true
// Enables proguard rules
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt")),
"proguard-rules.pro"
)
}
}
}

Add to the file android/app/proguard-rules.pro

## Flutter wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
// uncomment this if you are using firebase in the project
-keep class com.google.firebase.** { *; }
-dontwarn io.flutter.embedding.**
-ignorewarnings

Source

6. Obfuscate Your Code!

This function gives you both security and reducing size! here is how.

For Android:
Add to the file /android/gradle.properties

extra-gen-snapshot-options=--obfuscate

For IOS:

7. Use Google Fonts

This package 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.

8. DevTools

It can be used to see a visual representation of app performance, network, memory, CPU and much more. You can use it to reduce app size.

To activate the devtools run the following command,

flutter pub global activate devtools

To see the visual representation of the app,

flutter pub global run devtools - appSizeBase=apk-code-size-analysis_01.json

9. Enable more aggressive optimizations

android/gradle.properties

android.enableR8.fullMode=true

Removes unused codes, combines classes to make smaller the code, etc.

Explanation

10. Compress Native Libs

android/gradle.properties

android.bundle.enableUncompressedNativeLibs=true

Reduce the download size and the size of the app on devices.

Source

11. Split Bundle (for Android Only)

If we are uploading to the Playstore, we could create an app bundle, or we could split the apk per abi, which splits the apk into x64 and x86 bit code. Using appbundle, Google Play’s new app serving model, called Dynamic Delivery, uses your app bundle to generate and serve optimised APKs for each user’s device configuration, ensuring that they only download the code and resources required to run your app.

flutter build apk --split-per-abi

12. Deferred Components

Flutter has the capability to build apps that can download additional Dart code and assets at runtime. This allows apps to reduce install APK size and download features and assets when needed by the user.

Source

13. Detect heavy packages and get rid of them if possible

For Android’s AppBundle:

flutter build appbundle --target-platform android-arm64 --analyze-size

For Android’s APK:

flutter build apk --target-platform android-arm64 --analyze-size

For iOS:

flutter build ios --analyze-size

Explanation

14. Use Specific Libraries

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, If you’re using third-party packages, be mindful of their size. Some packages can significantly increase the size of your app.

15. Always Update Flutter

Flutter keeps on improving by latest updates that’s why, always be updated with latest technology.

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.

Conclusion

As Flutter continues to evolve, it’s likely that more tools and techniques will emerge to aid in size reduction. Staying abreast of these developments is essential for any Flutter developer. However, the principles we discussed — being mindful of resources, regularly auditing your app, and focusing on user experience — will remain evergreen.

--

--