One of the major challenges developers face in Android app development is optimizing app size without sacrificing functionality. Our team consists of only one Android Engineer working on the WINK+ app. Despite this resource constraint, we set an ambitious goal: to reduce our APK size to under 10 MB. A best-in-class product should look as good as it can be on the outside and the inside. Working with tremendous constraints forces us to think creatively to solve this. This is especially challenging when competing apps in the same category tend to be over 20 MB, and WINK+ offers much more complex features than them. One of the key bottlenecks we had was that reducing app size for the sake of reducing offers little to no value. Especially since we do not operate with abundant resources, we have to be very careful how we allocate them.
The first step in any app size optimization process is to gain a deep understanding of the components that contribute to the app size. For WINK+, this included resources like images, libraries, and redundant code. Tools like Android Studio’s APK Analyzer help break down the app’s APK file and identify the largest contributors to its size. Unsurprisingly, the main culprits were large image files and unused third-party libraries.
The most immediate win came from eliminating unused resources and libraries. Many apps include libraries that aren’t being fully utilized, either due to leftover features from earlier versions or third-party libraries that do more than required. We used Proguard, a tool built into Android Studio, to shrink and optimize the code. Proguard’s code shrinker helped remove unused classes, methods, and fields, reducing the overall size. Additionally, we conducted an audit to identify libraries that were too bulky for our use case.
One example is the QR Code Scanner, which we use for collecting WINK+ points all around Singapore. This is operated by MLKit under the hood. However, the MLKit library behind this takes up a healthy 2.4 MB of file size. However, because we only offer our app on Google Play and not on other third-party stores (which means all phones theoretically should have Google Play Services installed), we can unbundle the library and rely on Google Play Services. This effectively shaved 2 MB of size for us.
Fonts are another often overlooked aspect of app optimization. While they may seem small individually, fonts can add up quickly, especially when multiple font families or weights are included in the app. For the WINK+ app, we noticed that several unused font families and weights were being bundled into the final APK, contributing to unnecessary bloat. Removing these unused fonts helped us make a significant reduction in the app size without sacrificing the design or user experience.
We made sure to only include the essential fonts and weights that were required. Android allows you to define specific font weights and styles in XML using the font resource method, meaning that we didn’t need to bundle an entire font family with multiple weights and styles. By reducing the number of font variants and only keeping the ones actively used, we reduced the font asset size considerably.
Also, to avoid the need for downloading font assets from external servers (a process that can slow down app launch times), we embedded the fonts directly within the app, ensuring that the necessary font files were available offline. By carefully managing the fonts and removing the unnecessary ones, we were able to significantly reduce the size of the APK, and this optimization played a key role in keeping the app size under 8 MB.
One major change that contributed to the reduced app size was switching from bitmap images to vector drawables. Bitmap images, especially those used for icons and other scalable elements, can add significant size to an app. Vector images, on the other hand, are scalable and typically much smaller in file size. By generally replacing PNGs with SVGs and other vector formats, we were able to dramatically reduce the amount of storage space dedicated to image assets.
However, one of the issues we had was that a lot of the PNG files never was on Figma, as we inherited the app from elsewhere, and working files were already lost. As a result, we relied on online resources to help convert PNG to SVG. Despite Adobe offering a free service, We found this to be the most effective. (Adobe ends up keeping a lot of strange artifacts)
We also took advantage of Avocado, which allows us to further optimize the VectorDrawables by removing unnecessary points between lines, for example. However, some of the assets we migrated from PNGs had jagged edges, primarily because that’s generally how rasterized images end up being. We felt it was too much effort to clean that up, for a measly… few hundred bytes of savings, so we left them there.
Next, we took a close look at the third-party dependencies we were using. Many of these dependencies were large, adding unnecessary bloat to the app. One example was the Facebook Libraries.
We initially used this particular library, which loads up everything Facebook has:
// Facebook Android SDK (everything)
implementation 'com.facebook.android:facebook-android-sdk:latest.release'
However, since we do not use everything Facebook have to offer, we opted for a lesser variant, thus saving us a tremendous amount of space as well.
// Facebook Core only (Analytics)
implementation 'com.facebook.android:facebook-core:latest.release'// Facebook Marketing only
implementation 'com.facebook.android:facebook-marketing:latest.release'
By making sure that we only use dependencies that were strictly needed, we significantly reduced the app’s size. Techniques like “gradle dependency management” allowed us to strip down these libraries to their essentials, further optimizing the app’s build configuration.
Asset compression was another vital step in reducing the app size. Tools like ImageOptim allowed us to reduce a significant amount of image file size by repurposing images with better compression.
Android Studio of course allows one to automatically convert images to WebP, whenever ideal:
On WINK+, we use Lottie animations to enhance the user experience. Lottie files, which are JSON-based animations, have become a popular choice for app developers due to their lightweight nature and ability to scale without losing quality. They allow for smooth, high-quality animations that are much smaller in size compared to traditional video or GIF animations. However, even Lottie files can contribute to an app’s size if not optimized properly, especially if they include unnecessary layers or are too complex.
To reduce the overall size of Lottie animations used in WINK+, we employed several optimization strategies. First, we ensured that the animations themselves were as simple as possible. Lottie animations can sometimes include superfluous data, like extraneous keyframes or unnecessary assets embedded in the JSON file. Using the LottieFiles web-based asset optimizer, we were able to trim down these animations and remove unnecessary properties and redundant elements, making our Lottie files smaller and faster to load. We were, surprisingly, able to reduce around 1MB of file size just with this.
Once the app was optimized and its size reduced to below 10MB, we conducted extensive testing. It was crucial to ensure that the app’s performance, features, and overall user experience were not affected. We continuously monitored app performance on different devices. In our case, we use NewRelic for APM.
Reducing app size can significantly boost download rates, as users often prefer smaller apps due to concerns about data usage, download times, and device storage. Research indicates that for every 6 MB increase in an Android app’s size, the install conversion rate decreases by 1%.
This trend is even more pronounced in emerging markets, where data costs and limited storage are major considerations. In countries like India and Brazil, a 10 MB reduction in app size can lead to a 2.5% increase in install conversion rates.
In conclusion, reducing the size of the WINK+ app to less than 10MB while maintaining a wider range of feature sets compared to similar apps was a challenging but rewarding process. By leveraging strategies such as optimizing resources, modularizing the code, using App Bundles, and focusing on efficient compression techniques, we were able to deliver a lean, fast, and efficient app. As app sizes continue to grow across the Android ecosystem, this experience has reinforced the importance of size optimization — not just for user convenience but also for improving app performance and engagement.
Happy coding!