Optimize Your Android Application’s Size With Gradle Settings

Authors
Szymon Rybczak
Software Developer
@
Callstack

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.

diagram presenting the ratio increasing as app grows
Source: https://segment.com/blog/mobile-app-size-effect-on-downloads/

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: armeabi-v7a, arm64-v8a, x86, and x86_64. 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 apk 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 ./gradlew assembleRelease, use ./gradlew bundleRelease, but inside React Native Community CLI there’s a command that handles everything under the hood, so all you need to run is:

npx react-native build-android

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.

reducing the size of mobile app
Source: https://medium.com/google-developer-experts/exploring-the-android-app-bundle-ca16846fa3d7

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.

def enableProguardInReleaseBuilds = true

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

Insights

Learn more about Android

cover

Sep 16Article

Debugging Android Connectivity Issues with Metro Bundler

A practical guide to fixing the "Unable to load script" error in React Native when the Android emulator can’t connect to Metro.

cover

Jan 22Article

Writing a Native Module for React Native Using Kotlin

Check how to build a react-native-youtube-player, a Native UI component that allows playing YouTube videos in our React Native app.

cover

Mar 24Article

Android Drawer and StatusBar Done Right for React Native

Unlock best practices for Android Drawer and StatusBar implementation in React Native.

cover

Mar 19Tutorial

The Hard Way vs. The React Native AI SDK Way: Stop Writing Custom Modules for Every Model

Learn how React Native AI uses a unified provider model to switch between cloud and on-device LLMs without rewriting application logic, enabling reliable AI experiences online and offline.

cover

Mar 12Tutorial

Build Smarter Apps: Tool Calling & AI Orchestration Explained

Learn how on-device models in React Native can call tools, interact with external APIs, and return structured outputs you can use directly in application logic.

cover

Mar 5Tutorial

MLC LLM + React Native: On-Device AI Without the Pain

Learn how to run third-party on-device LLMs in React Native using MLC LLM. Choose your models, run them efficiently across platforms, and keep a unified JavaScript API with React Native AI.

cover

Feb 24Tutorial

Intelligent Fallbacks with Apple Intelligence in React Native

Learn how to use Apple’s built-in Foundation Models in React Native apps, reduce memory usage, and enable fast, fully on-device AI with React Native AI Apple.

cover

Feb 10Tutorial

What Is the React Native AI SDK? A Complete Intro & Quickstart

Learn why on-device AI matters for React Native apps, how local LLMs behave offline, and what problems React Native AI is designed to solve from day one.

cover

Jan 29Tutorial

Implementing an Android TurboModule with Kotlin

Learn how to implement a React Native TurboModule on Android, from the TypeScript spec and Codegen to the Kotlin implementation and package registration.

cover

Jan 19Tutorial

Working with Different Threads in Swift TurboModules

Learn how JavaScript, native module, background, and main threads interact in React Native TurboModules, and how to use GCD queues to run async work safely in Swift.

cover

Jan 9Tutorial

How to Add Type-Safe Constants to Swift TurboModules

Learn how to expose typed, immutable constants from a Swift TurboModule using Codegen, and get full end-to-end type safety between native and JavaScript.

cover

Dec 30Tutorial

Adding Event Emitters to Your TurboModule in Swift

Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.

cover

Dec 22Tutorial

Writing Your First TurboModule in Swift

Learn how to build a fully working TurboModule in Swift, integrate it with Codegen, and bridge it through Objective‑C inside an Expo app.