Mobile Development 18 min read

How to Supercharge iOS App Startup: Practical Optimization Techniques

This article explains how to measure, analyze, and dramatically improve iOS app launch performance through profiling, removing unused code, compressing assets, and restructuring view controller loading, illustrated with a real‑world WiFi manager case study.

Tencent TDS Service
Tencent TDS Service
Tencent TDS Service
How to Supercharge iOS App Startup: Practical Optimization Techniques

Introduction

This article describes how to optimize iOS app startup performance in four parts: basic concepts, defining optimization goals, a concrete case study of the WiFi Manager app, and a final summary.

Part 1 – Some Basics

1. App launch process

Parse Info.plist (splash screen, sandbox, permissions)

Mach‑O loading (select CPU slice, load dependent Mach‑O files, resolve symbols, run __attribute__((constructor)), load categories, run C++ static objects and ObjC +load)

Program execution (call main(), UIApplicationMain(), applicationWillFinishLaunching)

2. Measuring launch time

Cold launch (app killed) is the focus. Using Xcode’s DYLD_PRINT_STATISTICS environment variable (set to 1) prints a detailed timing report in the console.

Example report:

Total pre‑main time: 94.33 ms (100.0%)
  dylib loading time: 61.87 ms (65.5%)
  rebase/binding time: 3.09 ms (3.2%)
  ObjC setup time: 10.78 ms (11.4%)
  initializer time: 18.50 ms (19.6%)
  slowest initializers:
    libSystem.B.dylib: 3.59 ms (3.8%)
    libBacktraceRecording.dylib: 3.65 ms (3.8%)
    GTFreeWifi: 7.09 ms (7.5%)

Interpretation:

Pre‑main takes 94.33 ms.

Dynamic library loading dominates (61.87 ms); ObjC class initialization and other initializers consume the rest.

The three longest initializers are libSystem.B.dylib, libBacktraceRecording.dylib, and GTFreeWifi.

3. Factors affecting launch time

Before main()

Number of dynamic libraries

Number of ObjC classes

Number of C constructors

Number of C++ static objects

Number of ObjC +load methods

Experiments show that more libraries or classes linearly increase launch time; reducing them yields noticeable gains.

Avoid writing C constructors, C++ static objects, and ObjC +load methods when possible; use dispatch_once() instead.

After main()

Execution of main() itself

Execution of applicationWillFinishLaunching Loading of the root view controller, its child view controllers, and their view hierarchies

4. ApplicationWillFinishLaunching timing

Typical code in AppDelegate and view controllers is shown, illustrating the order in which -viewDidLoad methods are called.

Part 2 – Defining Optimization Goals

Aim to finish all work before main() within 400 ms.

Overall launch must stay under 20 seconds, otherwise the system kills the app.

The 400 ms target aligns with the duration of the iOS launch animation.

Part 3 – WiFi Manager Startup Optimization

Result before optimization (image omitted for brevity).

1. Remove unused dynamic libraries

Manually delete unnecessary libraries and re‑add only those required.

2. Remove unused classes

Use tools like fui (Find Unused Imports) to list dead classes, then delete them after manual verification.

3. Merge similar categories

Consolidate Objective‑C categories to reduce the number of extensions loaded at startup.

4. Compress image resources

Compress PNG assets (e.g., with TinyPNG) to reduce I/O during launch.

5. Optimize applicationWillFinishLaunching

Streamline business logic, reduce concurrent HTTP requests from 66 to 23, and move non‑essential work out of the launch path.

6. Optimize rootViewController loading

Analyze the UI hierarchy (image omitted) and defer loading of heavy child view controllers or subviews.

7. Handle background cold‑start scenarios

If the app is launched in the background (e.g., from Wi‑Fi settings), skip loading the root view controller entirely.

Part 4 – Summary

Use DYLD_PRINT_STATISTICS to profile pre‑main time.

Reduce the number of dynamic libraries, ObjC classes, and categories; scan for unused code regularly.

Replace __attribute__((constructor)), C++ static objects, and ObjC +load with dispatch_once().

Compress images within designer‑acceptable limits.

Analyze applicationWillFinishLaunching with anchor points and defer non‑critical work.

Delay loading of deep view controller hierarchies when possible.

Consider not loading the root view controller for background cold‑starts.

Remember that visual perception of speed often matters more than raw metrics.

mobile developmentOptimizationiOSdyldprofilingStartup PerformanceviewDidLoad
Tencent TDS Service
Written by

Tencent TDS Service

TDS Service offers client and web front‑end developers and operators an intelligent low‑code platform, cross‑platform development framework, universal release platform, runtime container engine, monitoring and analysis platform, and a security‑privacy compliance suite.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.