App Launch time in Swift

Updated 17 November 2023

Save

Introduction:

The first impression of any App is how fast the app is opening. When a User downloads an app from the AppStore all he cares about is: just click on the App Icon from the Home screen and experience everything the app has to offer as quickly as possible. So, the App Launch time will be minimum for the apps.

Types of App Launches:

Let’s analyze the problem statement, and to begin with we need to first understand the type of App Launches:

  1. Cold Launch: This simply means the App process does not exist in the System’s(OS) kernel buffer cache. Consider the app is launched for the first time or the device has been rebooted and the kernel cache is cleared. This is the worst case for the app launch and hence should be considered for the app launch optimization analysis. Which means every time you want to measure your app launch reboot the device.
  2. Warm Launch: This is the type of launch where the application process and data exists in System’s memory and all that System does is bring the app to the foreground from the existing instance of the app in the memory.

Types of App Launch Timing:

Let’s analyze the type of App Launch timings and see what we can do to make it better.

Coming back to the iOS world; The App launch time can be bifurcated into two:

1. pre-main() time:

This is the time before the UIApplicationMain is returned. Or to simply say, when your Application’s main() method is called and you get the control on the App by the OS. And you already must have realized so far, since this time is not in your control hence difficult to manage. However, dyld has a built in measurement(An environment variable: DYLD_PRINT_STATISTICS) to analyze this. Which is as depicted in the snapshot below.

Environment variable setting on Xcode to calculate the pre-main time of the App

And as you must already noticed the build configuration should be set to Release for the calculation, because this is the configuration with which the app will be released on AppStore. Also, it’s always recommended to do this exercise on an iPhone instead of a simulator. Once the configuration is done and the app is run, you would see the pre-main() timing details on the console something like this:

This data gives you an abstract idea about what it could be in your app that causes it to launch slowly. To know in depth about each of these types, I would recommend to watch the WWDC 2016 talk on Optimizing App Startup Time.

As mentioned in the talk the major reason for your App slow startup time could be the use of multiple dynamic frameworks. While Apple recommends to use only 6, but realistically speaking as your app includes more and more features, you tend to have multiple frameworks. Also, as you must already have been using Swift for your applications. Each application has to ship with the Swift standard libraries

Well, I believe these libs must be already optimized by Apple, but they still do exist. However, this is not in your control until we’ve complete ABI stability for Swift. Starting with Xcode 10.2 and iOS 12.2 the Swift standard libraries will no longer be shipped with the apps. This would reduce the thinned IPA size by ~9MB.
That being said the first and most important thing that you should consider doing is: Check for all your dependencies and if possible merge as many of them possible without breaking the logical boundaries of your application. The second step is to convert the dependencies to Static Frameworks instead of Dynamic Frameworks

Until Xcode 9, it was not possible to ship Swift frameworks as Static frameworks, but fortunately, Xcode 9 beta 4 onwards has ABI Source Compatibility, which gives you the flexibility to ship Swift Frameworks as Static Frameworks as well. All you need to do is just change the Build settings of the Framework target(s) as:

Please note this applies true for both Pure Swift frameworks as well as Frameworks which has both Swift and Objective-C in them.

Just by merging the frameworks and converting them to Static Frameworks you would see a great difference before and after for the pre-main() launch time of the application. A simple illustration is shown below with 4 Framework dependencies:

Dynamic vs Static Frameworks impact on pre-main() time

While this should help you win90% of the battle related to the pre-main()launch time of the app, the rest is related to coding best practices as illustrated in the WWDC talk.

Not only does static frameworks improve the app loading time, but they are also beneficial for the overall size of the app as well.

Moving on to next…

2. post-main() time:

This factor is something which you as a developer will have full control. Hence, this is very deterministic and easy to understand and manage. This starts with application:willFinishLaunchingWithOptions:and application:didFinishLaunchingWithOptions of your AppDelegate all the way up to the ViewController(s) viewDidLoad andviewWillAppear methods is when your User can see the “Welcome/Home” screen of your App.

Finally:

The simple equation comes out to be:

That being said, all of the above-mentioned strategies should be religiously check listed for every release of your app in order to have a better experience for the Users and hence maximum retention of your product.

author
. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


Be the first to comment.

Start a Project


    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home