Optimising Titanium App File Sizes

Axway Titanium SDK enables developers to create cross-platform, native mobile applications from a single codebase, making it easier and faster to build apps and really easy to add new features and maintain your code.

One of the challenges of developing in a single codebase is ensuring that only the relevant code and files are included in a particular platform build. Luckily, Alloy MVC makes this really easy by allowing you to identify what code, UI controls,
styles, and files are relevant to a particular platform, and should only be included in that platform.

When starting out on a new project, it’s really easy to drop your image files into app/assets/images and start coding — so it’s possible to end up with your iOS images (both retina and non-retina) in the same folder.

The problem here is that if you build to Android or Windows, the files in app/assets/images folder will all be included, even though they are not relevant to the platform. This means your Android build could include the iOS retina
images, increasing your app build size significantly.

Here are a few techniques you can use when building apps with Titanium to keep your app size as small as possible:

Use Platform Folders

Alloy MVC allows you to store Views, Styles, Controller and Assets (amongst other things) in platform-specific folders. If you do this, then only the relevant files etc will be included in the relevant build.

So, if you stored your images in app/assets/images/ then these files will be included in every build you do: iOS, Android, Windows. If your images folder has a load of @2x or @3x iOS retina images in the app/assets/images folder, you’re going to end up with some big Android and Windows app files that contain images only needed for iOS.

Given that image assets can be the most sizeable part of a build, it’s important to ensure that you include the relevant files in the relevant platform folders.

So, use:

  • app/assets/images/ for generic images that will on all platforms
  • app/assets/iphone/images for iOS images (e.g. retina)
  • app/assets/android/images for Android
  • app/assets/windows/images for Windows Mobile

Doing this will ensure only the relevant images are packaged into each build.

More info: Alloy Concepts

Create Buttons / Elements Using Code

When it comes to buttons, and UI elements, it’s easy for designers to produce graphical buttons for various control elements. Typically that means supplying various PNG files for different states and effects. Each image would have to have retina and non-retina
variants for iOS, or multiple densities for Android. You can end up with a lot of image files and this can increase the app file size significantly.

With Alloy and TSS, you can create classes or tag / id based styles to manage the look of your app. Applying a background colour, custom font, border radius effect, even shadows and gradients are all possible with just code.

This means no images to take up space and makes it more flexible to create buttons or elements on the fly without having to create new graphics.

You can even use Unicode strings for certain icons without any images being involved. Using code means you can create flat buttons, rounded corners even shadows etc. All this means less images, less files, and smaller app sizes.

Update As pointed out in the comments, its also possible to use font libraries like FontAwesome or Googles Material Icon Fonts to enable icons in your app without using graphic files.

More info: UnicodeAlloy Styles and ThemesFont Awesome

Use App Thinning For iOS

This is a feature introduced in iOS 10 that is enabled by default in the Titanium SDK. App thinning works by only downloading the assets required for a particular device from the App Store. This means that when you upload your app file to the
AppStore, that’s not necessarily the total size of the app that’s downloaded to the device. So, if you download an app to the iPhone, iPad files won’t be included. Likewise downloading an iPad app won’t include any iPhone-specific images. All this helps
to reduce the file size downloaded to the user’s device.

More info: Appcelerator Wiki — App Thinning

Download Content after Installation

It’s easy to package images, videos, files into an app when building it and forget about the total size the app will be when it’s deployed. For some apps, having preloaded content is a necessity but for others, having content pre-baked into the app is
actually more work as content updates require new updates to be published to the AppStore.

One technique you can use is to have a core app that when launched will download additional content from a remote server. There may be some restrictions/issues with this depending on the platform, so always good to check the Store rules, but most of
the time it’s fine to download remote content into your app. The downloaded content can be temporary, and removed easily OR permanently stored in the apps internal file storage.

With Android, it’s possible to use expansion files to have additional content that can be downloaded via the Play Store — there’s a native Android module available for Titanium to provide this capability.

More info: TiExpansionFiles

Targeting Specific Android Architectures

On iOS, all devices use some sort of A-based chip; the A8, A9, A10X etc. This means it’s easier to deliver one file package that works on all devices. On Android, there are two main architectures that are used depending on the device you use; ARM or x86.
Typically, Titanium SDK defaults to building for all types. This means the APK you create on Android contains all the relevant architectures to run on different devices.

A great feature of the Titanium SDK is the ability to create Android builds specifically for x386 and ARM only — and with the Google Play Store accepting multiple APK files as a single App version, this means you can create two architecture-specific builds,
upload them to the Play Store, and target just those specific devices.

(A quick test I ran reduced a 12mb application to 7mb just by building it for a specific architecture.)

More info: TiApp.xml reference (search for “arm” in the page)