← Back to list

How Swiggy Saved 3.7 MB by Solving a Vector Drawable Mystery

🎭 The Mystery Begins

Shivam Gupta in Swiggy Bytes — Tech Blog · 2026-07-10 05:14 · 31 claps · 4.1 min read
Open on Medium ↗
Wiki topics: RAG · RAG & Retrieval

How Swiggy Saved 3.7 MB by Solving a Vector Drawable Mystery

🎭 The Mystery Begins

Picture this: You’re a responsible Android developer. You’ve done everything right. You’ve replaced those bulky PNGs with lighter, elegant, scalable SVGs. You’ve patted yourself on the back. You’ve probably even tweeted about it.

Then one day, you open the APK Analyzer and see a familiar face staring back at you — a PNG you never invited to the party.

The Crime Scene

We recently discovered multiple instances where our APK analyzer reported mysterious size bumps. Upon investigation, we found PNG files that we absolutely, definitely, 100% did not add to our codebase.

Alongside our pristine SVG files, there were now multiple high-resolution PNG versions — one for each screen density (mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi).

Lets try to understand this better with one of our SVGs

The Case of random.png

We discovered a PNG, lets call it random.png had snuck into our APK like that one person who wasn’t invited to the party but somehow ends up in all the photos.

Plot twist: We never added random.png. We added random.xml.

So how did it end up in the APK?

🔍 The Root Cause (A.K.A. “It’s Not a Bug, It’s a Feature™”)

The automatic generation of these PNG assets comes from how the Android Asset Packaging Tool (AAPT2) handles vector drawables during the build process.

Here’s what the Android documentation says:

Android 5.0 (API level 21) and higher provides vector drawable support. If your app has a minimum API level that’s lower, Vector Asset Studio adds the vector drawable file to your project; also, at build time, Gradle creates PNG raster images at various resolutions.

Alright, that sounds reasonable… and with minSdkVersion 23, we should be safe. Right?

Upon deeper investigation into the VectorDrawable documentation (you know, the documentation nobody reads until something goes horribly wrong), we discovered the truth:

While basic vector drawable support begins at API 21, certain tags and attributes — like android:fillType and gradients in android:fillColor — were only introduced in API level 24.

If these newer attributes are present in your vector XML, AAPT goes:

“Oh, you’re using fancy features? Let me just generate PNGs for you.

Let’s look at our random.xml:

[embed]

See that gradient in android:fillColor? That feature was introduced in API 24. Our minSdkVersion is 23.

Since gradients were used heavily throughout the apps, all those assets automatically qualified for raster generation

Impact

While vector drawable XML files are typically lightweight, often just a few kilobytes, but they can significantly bloat the APK when they trigger automatic rasterization. The problem lies in the fact that rasterization process is opaque and we don’t know in advance how large the generated PNGs will be, and their size can vary significantly based on the complexity of the vector

For example, raster_prone.xml is only ~1KB as a vector asset. However, when rasterized by the build system, it results in a PNG file of approximately ~50KB.

As XML,

In Bundle,

For few assets, it generated PNGs worth ~200KB

The Plot Twist

AAPT2 generates rasterized PNG assets even for unused vector resources.

That’s right. You could have an SVG sitting in your drawable folder, referenced by absolutely nothing, forgotten by everyone, and AAPT will generate PNG versions of it even if you have enabled shrinkResources.

Solution?

The solve is to use VectorDrawableCompat by referencing vector assets via app:srcCompat, particularly for SVGs that include attributes not supported below API 24 and are prone to triggering rasterization.

Why VectorDrawableCompat?

VectorDrawableCompat is part of the AndroidX support library and renders vector drawables at runtime on devices running API levels below 24 without relying on pre-generated PNGs.

Also, we need to explicitly inform Gradle and AAPT that our project intends to use the support library for vector drawables to ensure that Gradle avoids generating density-specific PNGs and relies on the support library to render vector assets at runtime.

[embed]

🧹 What We Actually Did

Phase 1: Removed unused assets — especially vector files that were triggering rasterization. With these gone, they no longer made it into the build, preventing AAPT2 from generating those unnecessary PNG variants and reducing APK size.

Result — Download size reduced by > 1 MB.

Phase 2: minSDK bump to 24

Result — Download size reduced by 2.7MB

We observed a similar improvement in our shell apps (Toing-2.1MB, Instamart — 2.3MB) also.

References

About the Author:

An Android developer who has spent too many hours in APK Analyzer.

Acknowledgements

Big thanks to Sambuddha Dhar, Raj Gohil, and Tushar Tayal for always having my back. This milestone wouldn’t have happened without you all! 🙌


메타데이터
post_id
d8561877dbca
slug
how-swiggy-saved-3-7-mb-by-solving-a-vector-drawable-mystery-d8561877dbca
url
https://medium.com/swiggy-bytes/how-swiggy-saved-3-7-mb-by-solving-a-vector-drawable-mystery-d8561877dbca
canonical_url
https://medium.com/swiggy-bytes/how-swiggy-saved-3-7-mb-by-solving-a-vector-drawable-mystery-d8561877dbca
author_url
https://medium.com/@shivam.gupta.ndroid
status
ok
fetched_at
2026-07-11 07:22:59