iOS Launch Time Optimization - Related#
Background#
There are many articles related to optimizing the launch time of iOS apps. I didn't plan to write one myself, but I thought it would be more memorable if I organized my own impressions. Here, I plan to start from the aspects of principles, practice, and interview-related topics. First, we need to understand the principles of app launch and what happens during the launch. Then, we can explore the events during the launch process that developers can optimize and put them into practice. Finally, I will list some interview questions related to launch optimization, covering various aspects of the launch process.
Launch Principles#
Launch can be divided into cold launch and warm launch. Cold launch refers to opening the app from scratch after the app process has been terminated, while warm launch refers to bringing the app to the foreground from the background. When people talk about launch optimization, they usually refer to cold launch optimization. (Ps: In some versions, there is a bug where if you immediately reopen a just-terminated app, it will crash).
The cold launch process consists of two stages: pre-main
and post-main
.
Pre-main Stage#
As many articles have mentioned:
The pre-main stage consists of four parts: dylibs loading
-> rebase/binding
-> ObjC setup
-> initializer
. Each part has its own details... But every time I'm asked about this, it's really tiring to recite it from memory 😂.
Why does it feel difficult? It's because I don't know where these four steps come from, so I can only memorize them. I have a bad memory, after all, "I'm not young anymore".
So besides memorizing, what else can I do? Practice, and then understand. Things that have been done leave a deeper impression.
So let's see how to practice and understand:
First, open Xcode's Scheme, then under the Run options, select Environment Variables
and add Name as DYLD_PRINT_STATISTICS
and Value as 1
. Like this:
Then run it once, and you will see similar information printed in the console:
Total pre-main time: 599.52 milliseconds (100.0%)
dylib loading time: 101.25 milliseconds (16.8%)
rebase/binding time: 55.26 milliseconds (9.2%)
ObjC setup time: 189.95 milliseconds (31.6%)
initializer time: 253.04 milliseconds (42.2%)
slowest intializers :
libSystem.B.dylib : 6.65 milliseconds (1.1%)
libMainThreadChecker.dylib : 59.84 milliseconds (9.9%)
xxxTest : 313.12 milliseconds (52.2%)
Carefully compare the information in it: Total pre-main time
refers to the total time of pre-main
;
Total pre-main time
≈ dylib loading time
+ rebase/binding time
+ ObjC setup time
+ initializer time
;
In slowest intializers
, libMainThreadChecker
is because the Main Thread Checker
in the Scheme is turned on. You can turn it off by unchecking the following option.
So what happens in the pre-main
stage? It goes through dylib loading
, rebase/binding
, ObjC setup time
, and initializer time
. Now we know where these four steps come from. Next, let's see what each of these steps does.
Translated as follows:
Total pre-main time
refers to the total time ofpre-main
- Loading all dependent dynamic libraries
- Adjusting pointer offsets in
DATA
- Initializing all objects
dylib loading time
:- Loading libraries that the app depends on
- Loading libraries that the libraries depend on
rebase/binding time
:- Rebasing: Adjusting pointers in the image
- Binding: Setting pointers to external images
ObjC setup time
:- Registering objc classes (class registration)
- Inserting Category methods
- Ensuring each Selector is unique
initializer time
:- Initializing C++ static objects
- Loading objc's
+load
methods - Executing
main()
Post-main Stage#
Optimizing after the main function is also important. Everyone knows that application:didFinishLaunchingWithOptions:
is the method for initialization during launch. So what should be done here?
Let me ask you a question first.
Launch Optimization Practice#
Add sleep(10)
before return YES
in application:didFinishLaunchingWithOptions:
. As long as this method doesn't return, the LaunchScreen will be displayed, even if the home page has been initialized and the rootVC has been set, it won't be shown.
Interview-related#
When are +initialize, +init, and +load called? What is the calling order?
What is the difference between +initialize and +load?
Is +load loaded before or after the main function?
References#
Reducing Your App’s Launch Time
optimizing_app_startup_time
iOS Deep Thoughts | Measurement and Optimization of Launch Time