Reducing App File Size In Xamarin.Forms

The smaller your app file size the quicker end users can download it from the App Store. This may not seem like an issue, when your mobile is connected to WiFi, with a fast internet connection, but can be a concern if users typically download your app when on the move. Users may not download your app if they are using Mobile Data and you have a large file. I have mostly focused on Android in this post, as Android has the most significant app size issues.

File Size Comparisons

These comparisons are with a single page Xamarin.Forms application. I do mention a Native Xamarin.Android app and a Native Android app for comparison, just below.

  • Default: Standard settings when compiling an app
  • AOT: AOT was enabled
  • NoDebug: The nodebug option was enabled in the AOT Compiler
  • NoWrite: The no-write-symbols option was enabled in the AOT Compiler
  • Both: Both AOT Compiler options were enabled
  • ProGuard: ProGuard was enabled
  • All: Linker settings set to Sdk and User Assemblies
  • Sdk: Linker settings set to Sdk Only

The take away from this, is that No AOT, with the Linker set to Sdk And User Assemblies (All), will give you the lowest file size possible, but you miss out on the benefits of increased app start time.

With all options enabled, including AOT and ProGuard, for a single architecture, you get an increase in file size of about ~39%. Please note this percentage increase may go up or down, depending upon your code and resources. A blank Xamarin.Forms app, with AOT enabled, can only get down to 15MB at it’s best. Your app is going to be bigger.

If you don’t enable the other AOT options and ProGuard, but still use AOT, you may be looking at a ~65% increase in file size. The increase is more dramatic with multiple architectures selected.

Other Comparisons

A single page native Xamarin.Android application, with no AOT, Linking Sdk And User Assemblies, comes in at 5,800KB. With AOT, it jumps to 10,021KB. This is for armeabi-v7a only. No other options were set. A single page native Android application, comes in at a small 1,747KB. There is just no beating native, when you have the Mono overhead.

AOT in Android

If you use AOT in your app, to speed up the start times and performance of your app, you will notice that the file size balloons rapidly.

Android Aot Additional Arguments

Thanks to coming across a bug report, I actually found these interesting arguments you can pass to the AOT compiler, to reduce your binary size further. While I have not seen what happens to a stack trace, in any crash report, I can at least confirm, they do reduce your file size. As a precaution, I would ensure your analytics and logging is well written, to capture as much data as possible, to not rely on the stack trace. As a quick reference, you can add both of these to your Android csproj with the following.



In the resulting AOT, normally full method names are included in the resulting *.so files. You can stop this by passing this attribute.


Debug information may also be coming out in the final AOT binary, hence this option turns it off.

Drop x86 Support

This may not suit your needs, but if you have an app, designed only for mobile phone’s, there are actually hardly any phones out there, with support for x86. The Asus Zenfone 2 is the only one I have seen, and some reports put x86 usage in the 1% range. Dropping support for x86 could drop your package size by a large amount.

Split APK in Android

If you support multiple architectures (ABIs), using the Multiple APK Support, can let you generate a new package for each ABI. Google does caution you on this, but only because you have to support two APKs, there is actually no disadvantage for using two or more APK’s, except the additional overhead of actually having to create them.

To do this, you can check the Generate one package (.apk) per selected ABI. This will create an APK for each architecture you chose to support.

App Thinning in iOS

If you enable Bitcode, this option is on by default, you enable iOS to apply it’s app thinning, when you submit it to the App Store. As such, only the relevant code for each architecture will be sent to the users device, when they download your app.

Compress Images

If you have a lot of high quality images in your app, you can easily compress them, without losing any quality. Go to TinyPng, to compress PNG or JPEG files. I have seen image file size reduction at over 80% on some files, with no quality loss. It won’t help with memory usage, but could shave MB’s off your app package file size. Using SVG instead, is of course another option, if you are just starting to build your app.


ProGuard is normally known as a code obfuscator, meaning that it will try to scramble the method names and code structure if possible, to make it very hard for people to reverse engineer your code. I personally don’t believe in obfuscation, as it only slows them down, it never stops them. But in addition to this, ProGuard also optimizes and minimizes your code, resulting in additional file size reductions.


Xamarin.Forms and Mono, add quite a significant amount of overhead to the file size. AOT, amplifies that even further. Unfortunately not much can be done at this stage, however, with proper management, it is possible to get AOT working, with an acceptable file size, for a Xamarin app.


      1. Clay

        Thanks Adam. I do not see the option available in Visual Studio Community Edition for Mac. I am targeting the latest SDK (7.0), and the minimum is 4.4. Is this option available for non-enterprise VS? And in your experience, is it OK to use AOT for Android 6 as long as I’m targeting the latest SDK?

        I apologize for the questions, but I just can’t seem to find definitive resources for enabling AOT in Visual Studio. Some are putting configurations into csproj, and Xamarin documentation says it’s not available for Community Edition. Thanks Adam.

        1. Adam Pedley

          If you have the community edition, you will need to edit your csproj and put this in the appropriate PropertyGroup.


          1. Clay

            Thanks Adam. I added it, and the startup performance has been dramatically improved! I could not get ProGuard working though. I think it has something to do with Google Play Service versioning (I get a runtime linkage error when trying to execute GeofencingApi.AddGeofencesAsync). I’ll do some digging on that later.

            The performance boost is crazy…. Thank you!

  1. Dave

    I was recently trying to use AOT as the Android start up time improvement is noticeable, but abandoned it as my 50mb app (yes, not a great size I know) was showing up as 157mb once installed on the device! Have you come across this with any of these tests or know if there is a fix for that?

    1. Adam Pedley

      Have you dropped x86 support and compressed all your image files. AOT increasing file size to that extent isnt unheard of. You need to get your apk size down first, before AOT.

  2. Benjamin

    Under android with some build settings (I think it was enabling AOT) the app didn’t save their application properties in the properties dictionary (Application.Current.Properties[…])
    Every time the user removed the app from the task manager the settings were reset.
    So if you use some of these build settings and if you use the properties dictionary ensure that the values are saved properly

  3. Issac Kramer

    Does Proguard deals with mono/.net/IL code of the app?
    I thought it only deals with java code..

  4. Emil

    Hi Adam,

    Great article again. Thanks for making things so clear for us but very important feature is missing in your list ” bundle assemblies into native code”. I guess that it is only valid for VS enterprise users and not sure if some config changes can be achieved or not. It reduced my app size 39mb to 28mb and it makes execution faster also I believe.