How Gaode Map Supercharges App Startup: Deep Dive into Mobile Launch Optimization
This article explores why fast app startup matters, using Gaode Map as a case study to detail techniques such as Universal/App Links, H5 launch page handling, download size reduction, Android .so loading hooks, thread scheduling, task orchestration, and the tooling needed for performance analysis on both iOS and Android.
1. Optimizing Wake‑up with Universal Links and App Links
App acquisition and redirection rely on wake‑up protocols; custom URL schemes trigger system prompts on iOS and are disabled in Chrome 25+ on Android, requiring Intent wrappers. Platform‑standard protocols—Universal Links on iOS (iOS 9+) and App Links on Android (Android 6+)—allow direct jumps without prompts, though iOS does not support automatic wake‑up and requires user interaction.
2. H5 Launch Page Strategies
When an activity triggers an H5 page, slow loading degrades experience. iOS can use On‑Demand Resources (ODR) to pre‑download assets, falling back to a custom server if ODR fails. ODR also supports script pre‑loading, reducing bundle size and CDN costs. Alternatives include WKWebView pre‑loading via custom scheme registration, WKURLSchemeHandler, or a local server (the latter incurs higher startup cost).
3. Reducing Download Size
Large download sizes increase abandonment; a 200 MB+ app prompts users on 4G/5G. Gaode reduced size by moving the __TEXT segment to a custom section, cutting ~50 MB for pre‑iPhone X devices. Michael Eisel’s blog and tools like ZippyJSONDecoder, YYJSON, and custom linkers (zld) further improve load speed and lower cost.
4. Android .so Library Loading Optimization
Compile‑time static analysis : Use flags such as -ffunction-sections -fdata-sections for on‑demand loading and -fvisibility=hidden -fvisibility-inlines-hidden to hide symbols, avoiding unnecessary modules.
-ffunction-sections -fdata-sections // implement on‑demand loading</code>
<code>-fvisibility=hidden -fvisibility-inlines-hidden // hide symbolsRuntime hook analysis : Gaode’s Android team built a Frida‑gum based hook tool to monitor dlopen, find_library, and constructor calls, capturing load order and timing. Sample hook code:
#ifdef ABTOR_ANDROID
jint my_JNI_ONLoad(JavaVM* vm, void* reserved) {
auto ctx = asl::HookEngine::getHookContext();
uint64_t start = PerfUtils::getTickTime();
jint res = asl::CastFuncPtr(my_JNI_OnLoad, ctx->org_func)(vm, reserved);
int duration = (int)(PerfUtils::getTickTime() - start);
LibLoaderMonitor::getInstance()->addOnloadInfo(ctx->user_data, duration);
return res;
}
#endifParallel loading must avoid the loadLibrary0 lock; short‑duration tasks can run concurrently while long‑duration .so loads are serialized.
5. iOS App Loading Process
Before dyld_start, the app is forked via _mac_execve, Mach‑O parsing, and exec_activate_image(). Reducing dynamic libraries, +load methods, and static constructors shortens launch time; unused code should be pruned and monitored.
6. iOS Main‑Thread Method Timing
Use runtime swizzling to wrap +load and other entry points, recording timestamps before and after execution. Hooking objc_msgSend (via fishhook or a jump page) enables unified timing and can feed Order Files for launch optimization.
ENTRY _objc_msgSend
cmp x0, #0 // nil/tagged‑pointer check
b.le LNilOrTagged
ldr x13, [x0] // isa
and x9, x13, #ISA_MASK // class
...7. Post‑Entry UI Optimization
Pre‑emptively async‑initialize the next view controller during didTouchDown can shave 50‑100 ms from perceived response time.
8. Thread Scheduling and Task Orchestration
Prioritize essential startup tasks, defer others, and configure dependencies so that independent tasks run in parallel while dependent tasks follow a strict order. On Android, SharedPreferences loading can cause ContextImpl lock contention; merging files or serializing the load mitigates it. I/O tasks must balance speed, accuracy, and importance, considering fsync, write, and mmap behaviors.
9. Parallel Computation Models
Actor‑based models (Erlang, Akka, Go goroutines) isolate state and serialize message handling, avoiding shared‑memory pitfalls. Swift concurrency roadmap introduces actors and async/await, aiming to replace complex callback‑heavy code with safer, coroutine‑driven flows.
10. Startup Performance Analysis Tools
iOS : Instruments (Time Profiles → Samples) and MetricKit 2.0 provide fine‑grained CPU and custom signpost data. Automation can be achieved via usbmuxd, libimobiledevice, and idb to drive Instruments and collect traces.
Android : Android Profiler visualizes function execution time; combined with automated testing (Monkey, UIAutomator) it yields repeatable performance metrics.
11. Control‑Process Platform
An APM automation platform integrates daily iteration reports, integration gates, offline performance packages, automated test pipelines, and release gates. Collected metrics feed dashboards, trigger alerts, and create bug tickets for rapid remediation.
References omitted for brevity.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Developer
Alibaba's official tech channel, featuring all of its technology innovations.
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.
