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.
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.
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
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
First, edit [FlutterRoot]/packages/flutter_tools/bin/xcode_backend.sh
:
Locate the build aot
call, and add a flag to it,
${extra_gen_snapshot_options_or_none}
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.
10. Compress Native Libs
android/gradle.properties
android.bundle.enableUncompressedNativeLibs=true
Reduce the download size and the size of the app on devices.
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.
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
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.