Repository navigation
🚀 iOS Boot Time Optimization: Deep Dive & Universal App Insights #111
mayankmahavar1mg
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Investigation Goal: Optimize iOS app boot time for Catalyst Core Universal Apps
Test Device: iPhone X (2017, A11 chip)
Baseline Boot Time: ~5.1 seconds
Primary Bottleneck: WebKit WebContent process launch (2.0s = 39% of boot time)
Key Finding: Hardware-limited cold start, unavoidable on older devices
🎯 Why Universal Apps?
The Vision: Write Once, Run Everywhere
Catalyst Core enables teams to build one Catalyst application that runs on:
Business Benefits
Technical Architecture
graph TB A[Catalyst Application<br/>Your Business Logic] --> B[Catalyst Core Bridge<br/>Unified Native Integration] B --> C[Web Browser] B --> D[iOS WebKit] B --> E[Android WebView]🔍 Boot Time Investigation: Complete Analysis
Test Setup
Physical Device: iPhone X (2017)
Simulator: iPhone 17 Pro Max
📈 Boot Timeline - iPhone X Cold Launch
gantt title iOS Boot Timeline - iPhone X (5125ms total) dateFormat X axisFormat %Lms section Init App Init :0, 1020 section WebView WebView Creation :1020, 1033 section WebKit WebContent Launch :2053, 2000 section Navigation Nav Callbacks :4053, 431 section Render Page Render :4484, 348Detailed Boot Breakdown
Performance Breakdown Table
🔬 Root Cause Analysis
The 2-Second Wall
Why WebContent takes so long?
This is unavoidable on cold launch because:
🧪 Optimization Attempts
✅ Successful Optimizations
1. Early CacheManager Initialization
Before: Lazy initialization on first use
After: Initialize in AppDelegate.didFinishLaunchingWithOptions()
Impact: CacheManager ready when needed, no penalty later
2. Lazy Bridge Handler Loading
Before: All handlers created during NativeBridge init
After: Handlers created on first use
Impact: Saved 0.36ms (good practice, minimal gain)
3. Shared WKProcessPool
Implementation:
Impact: Clean architecture, process lifecycle management
4. Comprehensive Timing Instrumentation
Added
logWithTimestamp()at every critical step:Impact: Identified exact bottlenecks, enabled data-driven optimization
❌ Failed Optimization Attempts
1. Phantom WebView Pre-warming
Theory: Create dummy WKWebView early to pre-launch WebKit processes
Result: ❌ FAILED CATASTROPHICALLY
Why it failed: WebKit creates separate WebContent processes per WKWebView instance, even with shared ProcessPool. No process reuse possible.
2. HTTP Context Matching Pre-warming
Theory: Use
http://baseURL to match security context for process reuseResult: ❌ FAILED
Conclusion: WebKit's process isolation is strict. Cannot be bypassed.
🔍 Key Investigation Findings
Finding 1: Caching is NOT the Problem
Test: Disabled all caching via global toggle
Implementation:
Result: Boot time remained ~5100ms (unchanged)
Conclusion: ✅ Caching layer is NOT causing delays. Safe to use in production.
Finding 2: webView.load() is Synchronous (294ms)
Analysis:
Hardware comparison:
Finding 3: WebContent Launch is the Real Bottleneck
The Critical Gap:
Root Cause: WebContent process taking 2.0 seconds to launch
Why this matters:
Finding 4: SwiftUI View Recreation (Cosmetic)
Observation: WebView struct
init()called 10+ times during bootCause: SwiftUI recreates struct on every
isLoadingstate changeImpact: ✅ Negligible (0.02-0.45ms per init)
Attempted fixes:
Equatable.equatable()modifierResult: Still happens (SwiftUI's diffing algorithm)
Conclusion: Logging noise only, not a performance issue
📱 Hardware Comparison
iPhone X vs iPhone 17 Pro Max Performance
Key Insights
Hardware matters significantly
webView.load() is CPU-intensive
WebContent launch is consistent bottleneck
Simulator is optimistic
🎯 Best Practices for Universal Apps
1. Performance Expectations
Recommendation: Set minimum iOS version to optimize for target performance tier.
2. UX Strategies for Older Devices
Progressive Loading Flow
sequenceDiagram participant User participant App participant Splash participant Skeleton participant Content User->>App: Launch App->>Splash: Show (0-1s) Note over Splash: Brand logo Splash->>Skeleton: Transition (1-3s) Note over Skeleton: Loading indicators Skeleton->>Content: Hydrate (3-5s) Note over Content: Real data Content->>User: InteractiveWarm Launch Optimization
Strategy: Keep WebKit processes alive between launches
Impact: Subsequent launches much faster (pending test on iPhone X)
🏗️ Complete Boot Flow Architecture
flowchart TD Start([User Launches App]) Start --> A[iOS Process Start<br/>0ms] A --> B[SwiftUI App Init<br/>0-2ms] B --> C[AppDelegate.didFinishLaunching<br/>267ms] C --> D[CacheManager Init<br/>422ms] C --> E[WKProcessPool Allocated] D --> F[WebView Struct Init<br/>1316ms] E --> F F --> G[makeUIView - WKWebView Creation<br/>1316-2052ms, 388ms duration] G --> H[NativeBridge Init] H --> I[webView.load BLOCKING<br/>2054-2349ms, 294ms duration] I --> J{{WebKit Process Launch<br/>2349-4346ms<br/>2000ms BOTTLENECK}} J --> K[GPU Process 1008ms] J --> L[Networking Process 1001ms] J --> M[WebContent Process 2000ms] K --> N[Navigation Delegate Fires<br/>4346ms] L --> N M --> N N --> O[didStartProvisionalNavigation<br/>4777ms] O --> P[didCommit<br/>4865ms] P --> Q[didFinish - PAGE LOADED<br/>5125ms] Q --> End([App Interactive])🎯 Conclusion
graph TD A[Universal Apps Value] --> B[Single Codebase] A --> C[Instant Updates] A --> D[Reduced Cost] A --> E[Consistent UX] F[Investigation Results] --> G[2s WebKit Bottleneck] F --> H[Hardware Limited] F --> I[Unavoidable Cold Start] F --> J[Optimizations Done] B --> P{Production Ready?} C --> P D --> P E --> P G --> P H --> P I --> P J --> P P -->|Yes| Q[Ship It]Universal Apps with Catalyst Core provide immense value for cross-platform development:
The iOS boot time investigation revealed:
For best results:
The framework is production-ready. The 5s cold boot on iPhone X is expected behavior for 7-year-old hardware running modern WebKit. Newer devices will be 2-3x faster.
📊 Appendix: Complete Boot Logs
iPhone X - Cold Launch (Caching Disabled)
iPhone 17 Pro Max - Warm Launch (Caching Disabled)
Questions? Feedback?
Drop a comment in the GitHub Discussion or open an issue!
Last Updated: 2025-10-01
Test Device: iPhone X (2017)
Simulator: iPhone 17 Pro Max
Investigation Duration: ~4 hours
Total Tests Run: 15+ on physical device, 10+ on simulator
All reactions