The original address

Static linking

As we discussed in the iOS Boot Optimization from Exec () to Main () article, the dynamic linker does a lot of computing and disk IO when searching for dependencies.

Static linking eliminates the need for all dylib searches – dependencies and executables become one.

Therefore, some libraries can be statically linked to the main executable, reducing the number of frameworks and optimizing application startup time.

So how do you compile the framework as a static library?

In Xcode9, this can be set by MACH_O_TYPE = staticlib in Build Settings. When this flag is set, the linker generates static libraries. As for libraries that are integrated through Cocoapods, we have to create a custom script in our Podfile to set this flag for selected external libraries only during pod installation (that is, during dependency installation), because Cocoapods creates a new project structure for the managed library each time it is reinstalled.

If you want to perform static linking prior to Xcode9, you can use libtool.

In addition to dynamic libraries, the framework may contain resources (images, NIBs, and so on). We removed the dynamic library, but we couldn’t leave the framework with only resources. Bundle is a standard way to package resources in the Apple ecosystem. You can export all resources in the framework to *. Bundle by scripting. You then code your application to automatically use the correct resource location.

Let’s take a look at what happens to the startup time after static linking.

The graph below shows the change in startup time after the 26 Dylibs were statically linked on different devices.

You can see the startup time reduced by about 2 seconds on the iPhone 5C. On the iPad 2, the startup time improved even more — by about 4.5 seconds.

Note: If you have more than one statically linked library, be careful not to link it to more than one dynamic library – this can cause static library objects to be duplicated in different dynamic libraries, which can be a serious problem.

Dyld 3

Prior to iOS 13, all third-party apps were launched via Dyld 2. The loading process is described in the iOS boot Optimization from Exec () to Main (), which is not described here.

During the loading process of Dyld 2, a large number of calculations and I/O operations will be performed, which will prolong the startup time of App. So the apple development team officially introduced Dyld 3 at WWDC2017 in order to speed up startup.

Dyld 3 is divided into three components:

  • An out-of-process MachO parser.
    • All search Path, @rPaths, and environment variables that can affect startup speed are pre-handled.
    • Then the Mach-O headers and dependencies are analyzed, and all symbol lookups are done.
    • These results are eventually created as a launch closure.
    • This is a normal daemon process that can use the usual test architecture.
  • An in-process engine that runs startup closures.
    • This part is handled in the process.
    • Verify that the closure is safe to start, then map to dylib, and jump to main.
    • There is no need to parse the headers and dependencies of Mach-O, and there is no sign lookup.
  • A startup closure cache service.
    • The startup closure of the system App is built in a Shared Cache, and we don’t even need to open a single file.
    • For third-party apps, we build this startup closure when the App is installed or upgraded.
    • In iOS, tvOS, watchOS, all of this is done before the App launches. On macOS, thanks to the Side Load App, the in-process engine starts a daemon when it is first started, which can then be started using startup closures.

Dyld 3 prehandles a lot of time-consuming lookup, computation, and I/O operations, making for a big jump in startup speed.

Through the test, Dyld 2 and Dyld 3 startup time comparison:

launch type Dyld 2 Dyld 3
warm 0.722 s 0.731 s
cold 3.687 s 2.947 s

It can be seen that Dyld3 is 20% faster than Dyld2 at cold start

Static linking VS Dyld 3

The test results are as follows:

launch type Dyld 3 static
warm 0.731 s 0.679 s
cold 2.947 s 2.276 s

Through the test results, we can see that the App with static link starts faster than the App with Dyld 3.


Check us out for more iOS skills