First, cold start

In general, the cold launch process is from clicking on the icon to the didFinishLaunching. There are two stages to this process.

  • 1.main()Before that, the operating system loads the App executableMach-OTo memory, then perform load and link, then execute tomain(). Define this phase asT1
  • 2,main()Then, from themain()todidFinishLaunchingThe execution is complete. At this stage toT2
  • 3. It takes a while for users to actually see the content in a real project. namelydidFinishLaunchingAfter home page rendering, data request, positioning, etc. Define this phase asT3.

Through the above three stages. Try a cold start defined from a user perspective, T1+T2+T3. Each stage can be optimized,

Second, analysis and optimization

1.T1

The process of T1 is roughly as follows:

  • Load dyLD into App process,
  • Loading dynamic libraries (including dependent microdynamic libraries)
  • Rebase internal pointer adjustment.
  • Bind correctly points to the content outside the Image. Look it up in the symbol table
  • Initialize the Objective-C Runtime
  • Other initializations

mach-oExecutable files are all too familiar. The structure is

  • headerHeader, which contains the executable CPU structure, x86 ARM64
  • Load commandsLoad commands, including file organization and layout in virtual memory
  • DataData, containingLoad commandsData for each segment needed in.Section data

Section data contains

  • __TEXTCode snippets, read-only, including functions, and read-only strings,
  • __DATAData segments, read and write, including global variables that can be read and write
  • __LINKEDITContains metadata for method amount variables. And code signing.

Schema, reduce dynamic library, objC classes, methods, objC +load in the actual project T1 optimization space is not very large. +load can be replaced by +initialize. This can be done by looking at mach-O

  • __TEXT: __objc_methName: contains all the methods in the code
  • __DATA__objc_selrefs contains references to all methods used

2,T2

A lot of the startup tasks are done in the didFinishLaunching of your project. Initialize the SDK. The optimization space is relatively large.

Need to thin bodydidFinishLaunching. We sort them out by combing and reclassifying them, classifying them into categories, which ones we do early and which ones we do later. And set rules that can be followed in subsequent iterations.

3 startup

Create a startup manager and perform startup on the appropriate node. Keep the code simple and easy to read. Boot items can reuse code. This can be done by writing a pointer to a function to __DATA at compile time and retrieving it from the __DATA side at run time. Methods that address initialization can override all startup phases. This method is implemented by referring to QTEventBus. Clang has section methods

__attribute__ ((used, section ("__DATA,__QTEventBus"))) tells the compiler that this construct is in use, so write it to the __QTEventBus section of the '__DATA' section.Copy the code

4, T3,

Use a splash screen. The cache policy flashes

Build the home page UI when displaying the splash screen. Don’t waste time.

5. Practical operation

Use objc_Cover to detect. Run the Python script. An unused method is obtained. Lots and lots. Some of them were optimized after investigation. Next, re-optimize the boot items. Use BLStopwatch to print the time

Contrast. Macros define a set of plugins that listen for time.

AppDidFinishLuanch. The project uses the QTAppModule of QTEventBus to initialize the SDK. And it’s called asynchronously. But it doesn’t make sense to have all the initializations in one place. Optimized to about 2 seconds after operation