Shrink you apk size — (4) Reduce size of resources
In the last section, we try to remove as much resources as we can without impacting usability. And there is much more we can do about our apk by compress the resource further.
Compress Resource.arsc (not recommended)
This is most obvious solution that you may come up with. Since large chunk of resources is in Resource.arsc, it can save you much space if compressed, right? Well, while it do reduce the apk size, the decompression will takes extra memory and it will impact on your app start-up time.
Now we are talking. Normally the image will take up most space in your apk. Especially when you and app designer did not look into compression part. Let’s start with some tool at hand. Here I only consider open source lib that we can use without limitation. There are some online service like tinyPng you can choose from, but it could takes some money and there is not configuration which you can test on. Most importantly, you need to upload the file to them, which you won’t know what they will do with your file.
I tested the Quantpng, ImageOptim and Zopfli on some sample res folder which is about 6.9mb. In the end, ImageOptim shown the best compression rate. Here’s the result:
ImageOptim perform better compression compared with Quantpng and Zopfli because it’s actually combine OptiPNG, PNGCrush, AdvPNG, JpegOptim ,JpegTran, PNGOUT and Gifsicle. Be aware that ImageOptim only works on Mac.
I do tried Zopfli after ImageOptim which can save about extra 300kb. Running JpegTran along saved about 400kb.
Aside from that regular png compression, you can convert png to webp if your min sdk larger than 4.3(18). In previous case, it saved about 200~300kb after ImageOptim compression.
Although Zopfli do reduce the size with algorithm similar to webp, It could crash in some samsung devices on 5.0.1. So beware of your min sdk to prevent crashes.
In short, I suggest using ImageOptim with quality 70 and Zopfli deactivated. It is not likely to tell the difference, but you should create some sample and discuss it with designer that make sure you both happy with that. We will comes to that topic latter. You can run script on your spare mac which activated once a week and push the result if the size reduced.
Strange things that the size increased if I apply both ImageAlpha and ImageOptim increased the size (by 10kb). Theoretically It should be smaller.
For more detail about what combination of compression you should use, you can check the list. Since the image composition varies, you can try it on your own.
Get started with ImageOptim-CLI
ImageOptim-CLI add shell support on ImageOptim which enable us to run it with script (Of course you won’t want to do it manually). To install, simply run:
And move imageOptim, imageOptimAppleScriptLib, imageOptimBashLi, bpngquant to a folder on your idle mac which can access github, And add the following script that do the weekly trimming:
Noted that you still have to install ImageOptim, ImageAlpha or Jpegmini(not free) yourself, And you have to change the setting in ImageOptim manually because ImageOptim-CLI do not config it by parameter. And ImageOptim-CLI only works on mac, so you need to have a spare mac to run script on.
Is the quality acceptable?
It hard to tell if the quality is acceptable. I means, the acceptable quality varies from peoples. As engineers, we talk with metrics. Google awares of that and made Butteraugli, a library which tell the difference human eyes can perceive. You can use it to find the acceptable quality setting.
If we can configure the setting of ImageOptim with parameter, we can come up with a script that optimize each image and run Butteraugli. In each turns, we lower the quality a little. Use the pervious one if the quality is not acceptable. This way, we have each image optimized with it’s own config which with low disk size and acceptable quality. Sadly, ImageOptim-Cli and ImageOptim can not modify the setting yet. If it does, we can make a ultimate tool to optimize the images. If you have any ideas of how to set the parameter with some script, please leave you comment so that we can make it work.
Save more from Resource.arsc
We talked about Resource.arsc compression before, It takes extra memory and slow down your app startup. But still, there is some thing we can do about Resources.arsc.
Inside the Resources.arsc, it contains reference of all resources and some simple resources like styles. The mappings of id and folder can be proguarded by renaming the id and coordinating res path. The apk size will be reduced by about few hundreds kb.
Andresguard is a tool to proguard and reduce the Resources.arsc. You just pass the apk along with packing tool and keystore to do the magic. It will unpack apk, obfuscate the res name/ path, and 7zip/ sign apk. 7zip perform better compression than original one, which save about extra 1mb. It currently do not support Signature schemeV2. In short, it obfuscate res name and path, and use 7zip for better compression.
Here’s the script to trim the apk:
The script runs on Jenkins which is on unix. The zipalign_unix is the zipalign for unix (not the one you used on your mac), or you can specify the path to your zipalign folder.
In the config file, you should specify the whitelist, including some strings for 3rd party library, launcher icons, and the resources that used with getIdentifier(). Noted that you should install 7zip if you haven’t. Here’s the sample config file for andresguard:
You can integrate the script to you build script so that It will repack automatically. It take less then a minute, but do have some impact on you apk size.
Andresguard is also supporting gradle recently but I haven’t tried it yet. You can refer to github site for more info.
That’s all the resources compression for this section. Please leave your comment there is some technique I missed.
If you are interest in other trick to trim your apk down, you can read more from here.