Optimize Your Android Application’s Size With Gradle Settings
In short
This article discusses the importance of keeping Android app sizes small, emphasizing how larger app sizes can impact user experience, particularly in regions with limited internet access. It offers insights on optimizing app size through Gradle settings, enabling Proguard for release builds, and using App Bundles to reduce app size and improve distribution.
Originally published in December 2021, updated in April 2024.
Improve TTI, memory usage, and the size of your app
The small size of the app makes a difference for several reasons. First, not everybody has the luxury of using the latest device and having a stable and fast internet connection. This group of users may not be able to download and run your big-size apps, which can significantly reduce the number of potential users of your products.
Second, the bigger the size, the bigger the app's startup time. It takes much more time to make your product ready for the first interaction with a user when it’s too big. And that can seriously harm the user experience of your product.
Third, you need to remember that the app usually takes up more space after the installation. In some cases, they may even not fit into the device’s storage. In such scenarios, users may decide to skip the installation to avoid deleting their existing apps.
In this article, we will tell you how to avoid these unpleasant consequences of building big-size apps. Continue reading to find out how to optimize your Android app’s size with Gradle settings.
Why memory usage and the size of your app matter
At the beginning of each React Native project, you usually don’t care about the application size. After all, it is hard to make such predictions so early in the process. But it takes only a few additional dependencies for the application to grow from a standard 5MB to 10, 20, or even 50 MB, depending on the codebase.
Should you really care about app size? Why does a bundle size grow so rapidly? We will answer those questions in this section. But first, let’s have a look at what a typical React Native bundle is made of.
By default, React Native application on Android consists of:
- four sets of binaries compiled for different CPU architectures,
- directory with resources such as images, fonts, etc.,
- JavaScript bundle with business logic and your React components,
- other files.
React Native offers some optimizations that allow you to improve the structure of the bundle and its overall size. But they are disabled by default.
If you are not using them effectively, especially when your application grows, you are unnecessarily increasing the overall size of your application in bytes. That can have a negative impact on the experience of your end users.
Why is big APK size such a big deal?
The answer is simple.
A bigger APK size means more time needed to download from the app store and more bytecode to load into memory.
Let us explain what we mean in more detail.
It’s great that you and your team operate on the latest devices and have fast and stable access to the internet. But you need to remember that not everyone has the same luxury. There are still parts of the world where network accessibility and reliability are far from perfect. Projects such as Starlink already improve that situation, but that will take time to cover the most remote areas out there.
Right now, there are still markets where every megabyte of traffic has its price. In those regions, the application’s size directly impacts the conversion, and the installation/ cancellation ratio increases along with the app size.
It is also a common belief that every well crafted and carefully designed application not only provides a beautiful interface but is also optimized for the end device. Well, that is not always the case. And because the Android market is so competitive, there is a big chance that a smaller alternative to those beautiful yet large apps is already gaining more traction from the community.
Another important factor is device fragmentation. The Android market is very diverse in that respect. There are more than 20 popular manufacturers, each releasing an array of devices every year. Contributing to a relatively significant share of mid tolow-end devices, which account for over 60% of all smart phone sales annually. And those devices may face issues when dealing with bigger APKs.
As we have stressed out already, the startup time of your application is essential. The more code the device has to execute while opening up your code, the longer it takes to launch the app and make it ready for the first interaction.
Now, let’s move to the last factor worth mentioning in this context – the device storage. Apps usually end up taking up more space after the installation. Sometimes they may even not fit into the device’s memory. In such a situation, users may decide to skip installing your product if that would mean removing other resources such as applications or images.
Using Proguard for release builds to optimize app size
Leverage Proguard and architectural efficiency
Flip the boolean flag ‘enableproguardinreleasebuilds’ to true, adjust the Proguard rules to your needs, and test release builds for crashes. also, flip ‘enableseparatebuildpercpuarchitecture’ to true.
Android is an operating system that runs on plenty of devices with different architectures, so your build must support most of them. React Native supports four: <rte-code>armeabi-v7a<rte-code>, <rte-code>arm64-v8a<rte-code>, <rte-code>x86<rte-code>, and <rte-code>x86_64<rte-code>.
While developing your application, Gradle generates the APK file that can be installed on any of the mentioned CPU architectures. In other words, your APK (the file outputted from the build process) is actually four separate applications packaged into a single file with <rte-code>apk<rte-code> extension. This makes testing easier as the application can be distributed onto many different testing devices at once.
Unfortunately, this approach has its drawbacks. The overall size of the application is now much bigger than it should be as it contains the files required by all architectures. As a result, users will end up downloading extraneous code that is not even compatible with their phones.
Thankfully, you can optimize the distribution process by taking advantage of App Bundles when releasing a production version of your app. App Bundle is a publishing format that allows you to contain all compiled code and resources. It’s all due to the fact that Google Play Store Dynamic Delivery will later build tailored APKs depending on end users’ devices.
To build App Bundle, you have to simply invoke a different script than usual. Instead of using <rte-code>./gradlew assembleRelease<rte-code>, use <rte-code>./gradlew bundleRelease<rte-code>, but inside React Native Community CLI there’s a command that handles everything under the hood, so all you need to run is:
<rte-code>npx react-native build-android<rte-code>
The main advantage of the Android App Bundle over builds for multiple architectures per CPU is the ease of delivery. After all, you have to ship only one artifact and Dynamic Delivery will do all the magic for you. It also gives you more flexibility on supported platforms. You don’t have to worry about which CPU architecture your end user’s device has. The average size reduction for an app is around 35%, but in some cases, it can be even cut in half, according to the Android team.
Another way of decreasing the build size is by enabling Proguard. Proguard works in a similar way to dead code elimination fromJavaScript – it gets rid of the unused code from third-party SDKs and minifies the codebase.
However, Proguard may not work out-of-the-box with some projects and usually requires an additional setup to achieve optimal results. In this example, we were able to reduce the size of the mentioned 28 MB build by 700 KB. It is not much, but it is still an improvement.
<rte-code>def enableProguardInReleaseBuilds = true<rte-code>
Another good practice is keeping your eye on resource optimization. Each application contains some svg or png graphics that can be optimized using free web tools. Reducing redundant text from svg and compressing png images can save some bytes when your project has already too many of them.
Optimize your app with Gradle for smaller APK and faster TTI
All the mentioned steps are worth taking when you’re struggling with a growing application size. You will achieve the most significant size reduction by building the app for different architectures. But the list of possible optimizations doesn’t stop there.
By striving for a smaller APK size, you will do your best to reduce the download cancellation rate. Also, your customers will benefit from a shorter Time To Interactive and be more inclined to use the app more often.
Finally, you will demonstrate that you care about every user, not only those with top-notch devices and fast internet connections. The bigger your platform gets, the more important it is to support those minor groups as every percent of users translates into hundreds of thousands of actual users.
Need help with performance? Give us a shout!
If you’re struggling with improving your app performance, don’t hesitate to contact us. We’re the official Meta and Vercel partners, and we’ve been delivering high-quality solutions for our clients and contributing greatly to the React Native ecosystem for a while. If you’re on the lookout for a performance optimization partner, our React Native development company is surely the right one.