android app

Top 12 Ways to Reduce Android App Size During App Development Lifecycle

You’re reading this because…

  • You’re an Android app developer who hates to see phones running out of space.
  • You’re a patron of the 150 MP threshold Google Play Store puts on app download.
  • You’re tired of developing mammoth sized APK files that hardly get installed.

Let’s admit it: large size apps are storage-hoggers and downright nuisance. Users cannot do without them, nor can they get rid of them. They live in a constant love-hate relation with these apps – praising their rich graphics and smooth navigability, but cursing their sheer size at the end of the day.

And, because human needs are insatiable, they cannot help dreaming about ways to have more apps in their devices without compromising on quality or overtaxing the phone storage.

Beyond doubt, mobile devices have come of age with larger storage spaces. It has increased from a mere 16 GB 5 years ago to massive 256 GB. But, along with them, app sizes have grown, too.

Android users worldwide would unanimously agree to the fact that the largest chunk of their phone storage belongs to apps, which mercilessly gorge on data, RAM and most importantly, battery life.

Although there is cloud support for photos, videos, music, and other files, there is only so much a phone can take before it begins slogging and hanging.

Size is a Major Problem in the Realm of App Development

Don’t take our word for it. If we go by Google’s statistics, nearly 90% of mobile devices on this planet run on Android. The global user base is capped at 2.7 billion and the total number of apps available on Play Store is 2.8 million.

Adding to this, Google says if the size of an app is more than 150 MB (earlier 100 MB), chances are its installation is going to be lowered by 30%. For every 6 MB expansion in size, the install conversion rate could drop by 1%.

Android App developers should get all worked up about this matter because 70% users now consider the size of the app before installing it. And it’s no secret that an app that exists without considerable downloads is as good as non-existent.

The Question is Why Large Size Apps Exist in the First Place?

Modern-day apps have been puffed up because of three primary reasons:

  • Highly growing feature sets
  • Increasing UX expectations
  • Support for a wide range of screen sizes and densities

Hardly ever do these apps function efficiently. Beyond affecting the storage capacity and memory of mobile devices, they also increase data consumption. We can only imagine the woeful situation where a user relies on primitive Internet connectivity.

Thankfully, Google has a Way Out!

Even the tech giant is emphasizing on creating smaller apps and giving out tools for developers to make it happen. Its publishing platform, the Android App Bundle, enables users to install apps without re-downloading vital elements which are already present in other apps on Play Store, thus minimizing size. This is much like not having to buy utensils every time because you want to cook a certain recipe; the ingredients are just enough.

Google believes the platform can reduce app size by as much as 35%. This is pretty huge. Shrunken sizes will also mean quicker development time and TTM. Long story short, users will have more apps to look forward to without overwhelming their phone storage.

All a developer needs to do is upload the app as an Android App Bundle with all compiled codes and resources, and watch the platform defer APK generation as well as signing to Google Play.

This is followed by the app serving model, Dynamic Delivery using the codes and resources to generate APKs optimized in harmony with the varying device configurations and then, serving it to users for download.

The need to create multiple APKs and structure them to support different devices is dismissed. In return, users receive device-specific smaller versions of the app that can be downloaded without killing space.

But, There’s More to Downsizing Android Apps

The Android App Bundle cannot be the only key, can it? There has to be some collective effort from the developer fraternity as well to make sure Android apps do not eat up too much space on mobile devices.

But, before we proceed, here’s what you need to know about the APK file structure:

  • An APK is a ZIP archive that contains everything your app looks and works like.
  • It comprises Resources like Images and fonts with compiled code as Dex files.

An APK contains directories, which include the following:

  • META-INF/ with CERT.SF and CERT.RSA signature files, and a MANIFEST.MF manifest file.
  • assets/ with all assets retrievable using AssetManager objects.
  • res/ with all resources that are not a part of resources.arsc.
  • lib/ with a complied code for the software layer. Subdirectories: armeabi-v7a, arm64-v8a, x86, x86_64, and mips.

It contains files, which include the following:

  • AndroidManifest.xml which is always present, no matter what.
  • resources.arsc with all compiled resources and configurations of res/values/ folder.
  • classes.dex with all classes compiled in DEX file format.

Top 12 Ways to Reduce Apps Size During the Development Life Cycle

1. Image Optimization

Image size can be conveniently reduced without diluting the resolution. For instance, .jpg and .png images can be converted to .webp web image format to downsize apps without compromising the quality. The .webp format offers lossy compression like .jpg and transparency like .png. In short, it has the best of both the worlds.

There are a number of tools available for such conversion. Tools such as guetzli and packjpg suit .jpg file compression best while pngcrush, and zopflipng befit .png files. This apart, designers can implement vector graphics to create simple resolution-independent images that don’t crib for space.These are available in Android as VectorDrawable objects and enable a 100-byte file to generate images sharp and screen-sized.

android {
     defaultConfig {
         vectorDrawables.useSupportLibrary true
     }
 }

It is known that some images can do without static resources. The framework is more than enough to draw such images dynamically at runtime. Yes, using Vector Drawables objects is a brilliant idea when small size apps are to be developed.

They can survive on minimal space within the APK file and generate images compliant with the guidelines of material design. However, there could be a tussle when it comes to CPU and RAM usage as complex objects tend to slow them down.

Additionally, using the Draw 9-patch tool can also saves space. This is a WYSIWYG image editor and one of the coolest ways to cut image size. The tool lets you create bitmap images that can auto-resize to fit the different screen sizes of different mobile devices. Select parts within the image can be scaled vertically or horizontally depending on the indicators drawn in it.

Another way is to use the aapt tool to crunch .png images, the resources of which are present in res/drawable/. The compression is lossless. For instance, a true-color .png image which doesn’t need more than 256 colors can be converted to a color palette enabled 8-bit one. The latter retains the quality but sheds the size.

However, developers must remember that the aapt tool would not compress .png files in the asset/ folder. Also, it will not be able to optimize any image that uses more than 256 colors. Additionally, it might puff up .png files which have already been shrunk. This disadvantage can be ignored by using the cruncherEnabled flag in Gradle as such:

aaptOptions {
    cruncherEnabled = false
}

2. Redundant Code Removal

While developing a mobile app, it is fundamental that you get the hang of a code’s footprint within a redundant system where it is automatically generated. For instance, there are a number of protocol buffer tools that can create methods and classes in surplus.

These methods and classes do not do any good to the app. Instead, they simply expand the size of the app swiftly. Such repetitive codes need to be removed so the app size remains optimum without the oppression of indulgent superfluous parts.

3. Dead Code Elimination

The size of the APK file is directly proportional to the load speed of your app, the memory it uses and the power it consumes. As such, any unused or inoperative code kept just for the sake of keeping will only add to the bulk. Much like the removal of redundant codes, dead code elimination is necessary for your app to stay energized any time, any day.

The process has zero impact on the functionality of the app, because such codes aren’t part of it in the first place. However, removing them enhances the quality of the source code and lowers the need to maintain code size. Also, introduction of bugs is prevented, thus manifesting a healthy app, overall.

4. Removal of Unused Resources and Class

A static code analyzer called lint is part of Android Studio and can detect resources in the res/ folder not referenced in the code. Such resources are unused and therefore, pointless. Whenever the lint tool finds such a resource, it prints this message:

res/layout/preferences.xml: Warning: The resource R.layout.preferences appears
    to be unused [UnusedResources]

For instance, when you add libraries to the code, unused resources might follow. The lint tool will detect this and send you the alert. However, developers should keep in mind that the tool would skip scanning the assets/ folder or the assets a code references via reflection or even the library files developers link to the app. And, never ever will it remove resources on its own!

For the automatic removal of unused resources and class, Gradle is the best tool. You simply have to enable code shrinking so you can use shrinkResources and allow it in the build.gradle file of the app.

During this process, another tool called ProGuard will come into play. This one is a Java class file shrinker, obfuscator, optimizer, and preverifier that can identify and remove unused resources, classes, methods, fields, and attributes or rename these using short names that hold no meaning. It can remove all unused methods and trim the classes.dex file once you set minifyEnabled to true.

android {
    // Other settings

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

However, in this case, ProGuard will only remove unused code followed by Gradle removing the unused resources.

Once you declare the configurations supported by your app, Gradle provides the build system with the necessary information with the help of the resConfig, resConfigs and thedefaultConfig options. Using this information, resources from unsupported configurations are prevented from appearing in the APK by the build system, thus bringing down the app size.

5. Reuse of Resources

Reusing is better and easier than removal. It is also an amazing way of utilizing resources for other tasks. For instance, you might have a discreet resource to define variations in an image pertaining to shades, tints, and orientation.

However, you could also use the same resource for other images, customizing as and when required. Reusing resources further helps in keeping the scrolling performance of an app optimum and reducing its size considerably.

Android offers a number of utilities to alter the properties of assets. For instance, to change the color in an image developers can use the android:tint and tintMode attributes on higher versions or ColorFilter class in lower versions.

Yet again, some resources are only a rotated equivalent of another, which can be omitted. Here’s a classic example of turning the ‘thumb up’ into a ‘thumb down’ by central pivoting and rotating by 180 degrees:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns_android="http://schemas.android.com/apk/res/android"
    android_drawable="@drawable/ic_thumb_up"
    android_pivotX="50%"
    android_pivotY="50%"
    android_fromDegrees="180" />

6. Minimized use of Resources from Libraries

External libraries are often utilized while developing Android apps so usability and versatility can be delivered to the utmost. The common ones are Google Play Services, which is used to retrieve auto translations of app text and Android Support Library, which is used to up the user experience on dated devices.

However, such libraries are also designed for servers or desktops and come with loads of methods and objects that don’t serve the app any purpose. However, you can edit the files and retain only those parts which your app requires.

Of course, for this to happen, you’d need modification permissions. Alternatively, you can also use a mobile-friendly library for specific functionalities.

7. Support for Specific Screen Densities

Think about those zillion Android-enabled devices that beep worldwide. Think of the platform supporting them. Yes, Android is easy with a colossal quantity of mobile devices with varied screen densities, including ldpi, tvdpi, mdpi, hdpi, xhdpi, xxhdpi, and xxxhdpi.

However, you do not need all of them for your app. You can always do without exporting rasterized assets to each one of them.

Here’s how you can do it: Make a survey to determine the percentage of users with devices that have specific densities. If this percentage is insignificant, why bother bundling all those densities in your app? After all, even if you don’t include them, Android would step in automatically scaling the available resources meant for other densities.

android {
    splits {
        density {
            enabled true
        }
    }
}

8. Reduction of the Size of Native Binaries

In case your app runs on native code, this is an effective way to reduce the quantity of native and Java codebase as well as shrink the size of the release version. There are two primary ways to bring down the size of Native Binaries:

  • By using the arm-eabi-strip tool in Android NDK to get rid of useless debug symbols
  • By setting android:extractNativeLibs=”false” to avoid the extraction of native libraries by preventing PackageManager from copying .so files from APK to file system.

9. Avoidance of Enumerations

Enums are tricky. A single one can add anywhere from 1.0 to 1.4 KB to the classes.dex file of an application. These can accumulate at ninja speed, especially if there are shared libraries or complex systems.

This is why it is better to steer clear of enumerations. How? – By using ProGuard and the @IntDef annotation to convert enumerations into integers. In return, you would have a reduced size with all the goodness of enums intact.

10. Maintenance of Multiple APK Files

Some APKs come with content that gets downloaded but is hardly ever used. For instances, add-ons like additional languages are not always a necessity, but are downloaded anyway. This not only consumes data but also enlarges the application and takes up space in phone storage.

One solution to this has been already discussed – to upload the app in Google Play via the Android App Bundles, which allows Google to enable optimized APKs according to device configuration.

Alternatively, you can also divide it into multiple APKs based on specific assets. When you do this, users receive the only that APK which complements the device features and settings. For instance, if a certain mobile device comes with hdpi, it would not need xxxhdpi resources, would it?

11. Implementation of Downloadable Fonts

This one is a new addition to Android. Google recognizes the fact that a majority of applications on Play Store have fonts in common. However, these fonts are already a part of the app bundle.

As a result, different applications on the same device carry duplicates of the same fonts. This apart, almost all of these apps haven’t been optimized for mobile devices. This is why Google has decided to introduce Downloadable Fonts in its Support Library 26.

downloadable fonts process

Accordingly, APIs can now request fonts from a font provider application and do away with bundling files into APK or letting application files download fonts. Downloadable Fonts not only reduce the size of APK files but also help in saving cellular data and phone memory.

12. Utilization of APK Size Analyzer

If you want to find out what’s inside your app, the APK Size Analyzer is an awesome tool. It is perhaps the easiest way to work out and implement ways that would lead to app size reduction. There are two methods to do it:

  • In the Android Studio

The Android Studio comes with a plugin marketplace which can be used to download the APK Size Analyzer. Here’s how to do it:

Android Studio > File > Settings > Plugins > Marketplace > Android Size Analyzer > Install > Analyze > Analyze App Size

You will receive a tool window with all information on how to cut app size.

  • From the Command Line

Alternatively, you can download the APK Size Analyzer from GitHub in the form of a TAR or ZIP file. Once you have extracted the archive, run the size-analyzer script or size-analyzer.bat script with the help of these commands:

./size-analyzer check-bundle 
./size-analyzer check-project 

To Conclude…

The lessons you have learnt so far:

  • Why Android apps have been becoming bulky over the years.
  • Why it is important to focus on smaller app size.
  • How to reduce Android app size during and after development.

Remember, slimmer the app higher would be the download rate. So, work on these tips and squeeze the waistline of your app as tightly as you can.

After all, if you have reached so far in this article, it is for sure, you really are that developer who isn’t very happy about mobile apps unabashedly occupying disk space and receiving the hate from potential users.

Get started today!

Found this post insightful? Don’t forget to share it with your network!
  • facebbok
  • twitter
  • linkedin
  • pinterest
Avatar

Akash Patel is Sr. Android Engineer at Mindinventory. Hardworking and dedicated person, love to explore, always have a big hunger for new knowledge. Proficient in object-oriented design, data structures, problem-solving, complexity analysis, and debugging. Providing oversight and mentorship to a team of developers.