Background: When checking the App startup time in the background, some can reach 2-15 seconds. Party A’s father in the Middle East couldn’t stand it and decided to take time to optimize the startup time.
The startup time of the App refers to the time from when the user clicks on the App to when the user sees the first interface; that is, when or when didBecomeActive
rootVC .viewDidAppear
Optimization Results
The original variable duration is reduced from 2-15s to about 800ms.
Boot process
Cold start time
First, look at the cold start time consumption, which is mainly divided into pre-main
stages and main()
stages. Next, check the time consumption and optimization in these two stages.
1. pre-main
Stage time consumption
dylib loading time
: Dynamic library loading timeThere are 8 built-in customized IMLib SDKs, only 2 of them can be used, and they have not been processed.imlib imlibcore chatroom location customerservice discussion publicserice translation
rebase/binding time
: Correct the time consumption of symbols and bound symbols2.1 rebase: The address of the project printed by image list + the Address Size of _main in linkMap is the memory address of the actual main function, which is the accurate address (dis-s 0x00000001049+0x6194)
2.2 binding: iOS system executable file in App , add a symbol, and when it is run, the system will bind our symbol and find the real external function.The App’s UI has been modified several times, and the page and architecture have been reconstructed two or three times, leaving a bunch of redundant code that has not been cleaned up.ObjC setup time
: Objc class registration, category definition, insertion method list, and time-consuming to ensure that the selector is uniqueinitializer time
: Time-consuming creation of +load() of the Objc class, C++ constructor attribute function, and C++ static global variable creation
2. main()
Stage time consumption
Mainly due to application:didFinishLaunchingWithOptions:
the time-consuming SDK initialization, business registration, business processing of each module, etc.
Optimization
1. pre-main
Stage optimization
- Dynamic library processingDelete/merge 5 dynamic libraries, and finally 3 remain.
- Remove IMLib’s dependency on
customerservice
,discussion
,publicserice
and delete the command from the packaging script
- Remove IMLib’s dependency on
- Because only the location messages in the location library are used and the others are not used, the location messages are merged into IMLib and the location library is deleted.
- Clean up useless classes, categories, and methodsPerform static analysis through Code->Inspect Code in AppCode and delete it after confirming it is useless.
- Reduce C++ constructorsC++ objects are basically in the underlying protocol stack and are not processed.
- Binary rearrangement (Clang instrumentation)The leader does not recommend adjustments at this stage and has not yet been processed.The number of PageFaults is related to the amount of code. How to reduce the number of Page ins: put the methods that need to be called together at startup, and those that do not need to be called at the back (optimizing the executable file)
2. main()
Stage optimization
Move unimportant business to the back (startup items to the back)
- IM connections are migrated to child threads (because they will be stuck by the protocol stack in some cases)
- In addition to injector registration and other necessary businesses
application:didFinishLaunchingWithOptions:
, the others are migrated toapplicationDidBecomeActive
3. Start the optimized show operation
During cold start, the App first loads a VC that is exactly the same as the startup image, and then initializes the rootVC of the business after the VC is displayed.
4. Other processing
For GCD queues created by developers, the default QoS is actually User-Initiated. User-Interactive and User-Initiated obviously preempt the main thread. Try to set threads unrelated to startup to Utility or Background to reduce preemption of the main thread.