How to Cut iOS App Startup Time by 40%: Deep Dive into dyld Loading and Optimizations
This article explains the iOS app launch process, breaks down dyld's loading stages, proposes concrete optimizations for dynamic libraries, rebasing, Objective‑C setup, and main‑thread work, and shows how these changes achieve roughly a 40% reduction in startup time on an iPhone 8.
Background
For users of the Snowball (Xueqiu) app, real‑time market data and trading are critical, demanding fast app launch. The app combines community features and trading, integrates many third‑party services and libraries, which can slow startup if not managed properly.
Technical Principle – dyld Loading Process
When iOS receives a request to open an app, it first loads the executable and then its dependent dynamic libraries (dylibs). All system frameworks are dylibs, and since iOS 8 developers can also create their own dylibs. However, sandbox signature verification prevents remote updates of dylibs.
The dynamic linker dyld controls the loading sequence after the kernel hands over control. The steps are:
Load dylibs image
Rebase image
Bind image
Objective‑C setup
Initializers
Load dylibs image
Three main image types are involved:
Executable files (e.g., .o)
Dynamic libraries (dylib)
Bundles that cannot be linked directly and must be loaded with dlopen The loading workflow includes:
Read the executable header to obtain the list of dependent dylibs
Locate each dylib
Verify it is a Mach‑O file and open it
Register the file signature with the kernel
Call mmap() on each segment of the dylib
Optimization tips:
Reduce reliance on non‑system libraries; merge them or replace with static resources.
When using CocoaPods, avoid use_frameworks! which forces all pods into dynamic frameworks. From CocoaPods 1.4 onward, set s.static_framework = true in the podspec to build static libraries.
Rebase / Bind
Address Space Layout Randomization (ASLR) introduces an offset between the loaded address and the expected address. rebase fixes internal pointers; after that, bind resolves pointers to external symbols.
Optimization tips:
Reduce the number of classes, categories, and selectors.
Limit C++ virtual functions.
Prefer Swift structs over classes to lower symbol count.
Objective‑C Setup
This stage registers Objective‑C classes, reads category and protocol information, and ensures selector uniqueness.
Optimization tip: Apply the same reductions listed for the previous step (fewer classes, categories, selectors).
Initializers
After static adjustments, dyld runs initializer functions, including +load methods for classes and categories, C++ constructors, and creation of static global variables. Once completed, control passes to the app’s main function.
Optimization tip: Decrease the number of +load method calls.
Main Function Flow
The path from entering main to displaying the home screen is:
main → applicationWillFinishLaunching → didFinishLaunchingWithOptions → Home page renderingDevelopers typically do not intervene in the first two steps, so optimizations focus on the latter two.
didFinishLaunchingWithOptions
This method mainly:
Sets up the root view controller of the main window.
Initializes all required global services.
Optimization tips:
Delay initialization of third‑party libraries when business logic permits.
Postpone non‑critical runtime tasks such as version checks or non‑essential data updates.
Home Page Rendering
To display the home page, the app must render the view hierarchy and fetch business data.
Optimization tips:
Implement the UI in code rather than using XIB files.
Streamline calculations inside viewDidLoad and viewWillAppear.
Use caching to pre‑show home‑page data.
Testing Methodology
For pre‑main timing, set the environment variable DYLD_PRINT_STATISTICS=1 to obtain dyld statistics in the launch log. For after‑main timing, insert code that logs the current timestamp at relevant points.
Tests were run on an iPhone 8, comparing average launch times before and after applying the optimizations.
Results
The optimizations yielded roughly a 40% reduction in launch time, shaving about one second off the total startup duration (the gain is larger on older devices), providing a perceptible improvement in user experience.
Snowball Engineer Team
Proactivity, efficiency, professionalism, and empathy are the core values of the Snowball Engineer Team; curiosity, passion, and sharing of technology drive their continuous progress.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
