Desire for the most part, since the world is speeding up, users have very little patience to wait for an application to load. If an application is slow to load, the user will get frustrated, have a lower retention rate and will leave negative app reviews. Speeding up app launch time is very important for iOS developers from the perspective of creating a smooth user experience as well as for making the application work well.
Here we try to highlight tried and tested strategies to cut down on app launch time and give your app that racing feel where the launch seems almost instantaneous when the button is pressed.
This method is invoked during the start of the app and thus almost any work done here delays the launch time.
Optimizing tips:
Do not perform time consuming tasks at this time the kind tasks of fetching data from an application or the Internet or even loading large files.
Defer tasks that are non critical to the first time experience for the user.
Use a thread background to load nonessential data after the application has launched.
Example: Rather than initializing directly in didFinishLaunchingWithOptions, place it on a background queue:
DispatchQueue.global().async {
// Load resources or perform tasks in the background
}
The main thread is responsible for rendering the user interface and for user interactions. Any blocking task on the main thread will delay the start up and give a poor user experience.
Avoid:
Long-running tasks such as JSON parsing, database queries or large file reading.
Synchronous network calls.
Solution:
Heavy computing should be done on background threads, like GCD or OperationQueue.
Example:
DispatchQueue.global().async {
let data = fetchData() // Expensive task
DispatchQueue.main.async {
updateUI(with: data)
}
}
An increased app binary size affects the time needed by the app to load itself onto memory. This is what chopping down your binary size achieves allows for a quicker app launching performance and also enhances download times and storage requirements. How to Reduce Binary Size:
Removing unused assets images and code.
Compressing images with tools such as ImageOptim or TinyPNG.
Use vector images (PDF) instead of raster images where possible.
Enable Bitcode in your project settings.
Strip unnecessary architectures by configuring EXCLUDED_ARCHS.
The present narration on the Optimization of Storyboard and Xib will infuse hairy overhead in the launch of the application if these elements are too huge or complex.
Best Practices:
Break up large storyboards into smaller ones for different modules or flows.
Using state based light views on your first screen will result in an equally easier Loading process.
Keep as Anticipated: Avoid excessive auto layout constraints in your initial views.
Alternative: For advanced apps that require quick initialization, consider doing UI creation entirely through code (i.e., SwiftUI or UIKit).
You do not force the application to load all the resources when starting, this will considerably slow the launch time. Lazy loading means loading the resources when you require them.
What to Defer:
Images, videos or heavy data sets
Frameworks or services that are not beneficial to user experience
An example of this is lazy initialization of properties:
lazy var heavyResource: SomeResource = {
return SomeResource()
}
Third party libraries and frameworks sometimes cause too much overhead in the launch process of the application. You should assess and refine your dependencies to achieve better performance.
Steps to Optimize:
Unused or old dependencies should be removed.
Prefer lightweight libraries.
Initialize dependencies lazily and not at startup.
Check for 3rd party framework's possibility to block the main thread.
Example: Delay initialization for all analytics frameworks after the app launch, if you are using them.
Dynamically loading assets during the application launch causes additional overhead before the first screen is displayed. Use precompiled assets to lessen runtime overhead.
Suggestions:
Precompile the Asset Catalog app images, icons and other media for use and assembly.
Precompile SwiftUI previews or components for faster loading.
Any application relying on JSON or another data format may experience an extremely slow startup due to poor parsing.
Optimization:
Using fast libraries such as Codable to parse JSON.
Prefetch asynchronously.
Cache data, using Core Data, Realm or UserDefaults to avoid fetching at launch time.
Profiling with Apple's Instruments is a great way to identify performance hiccups in your app. Measure and identify the launch time and areas to improve it.
Instruments to Know:
Time Profiler: Where does the time running your app go?
Activity Monitor: Launch CPU and memory usage.
System Trace: Overall measurement of app performance.
Keychain or database access during the launch might introduce a slight delay. Such activities are usually slower because they use encryption, and then that decryption occurs.
Best Practices:
Cache frequently accessed data in memory or UserDefaults.
Defer Keychain queries until necessary.
For iOS 13+, the SceneDelegate takes care of your application's UI lifecycle. The AppDelegate and SceneDelegate should be optimized to avoid unnecessary initializations.
Tips:
Keep application(_:didFinishLaunchingWithOptions:) clean.
Offload things that are not time-critical to background queues or lifecycle events such as viewDidAppear.
The purpose of prewarming techniques on iOS is to boost the responsiveness of an application by preparing resources in the background.
How to Implement:
Make use of silent push notifications or background fetch to fetch any resource that would be loaded by the actual user action.
Cache results such that you can afford to scale down runtime processing at startup.
ODR allows you to load app assets from Apple's servers only when they are really needed, which ideally reduces the size and startup time of the application. Example Use Case: If your app has a tutorial, large media file or the like, load it when the user navigates to that part.
Targeting the latest iOS (iOS 15+), your app should now be taking advantage of Swift's concurrency model to manage async tasks better (with async/await).
Example:
@MainActor
func fetchData() async {
let data = await loadHeavyData()
updateUI(with: data)
}
For the last touches to your application, you can consider the use of a very simple and static launch screen, giving your user the perception that your app launches faster. This would mean that the very first screen of the application will form part of your transition from great splash to the main parts of your app.
Certainly, app launch time optimization is one major aspect of providing a rich user experience. Adopting these techniques from deferring heavy tasks to using the new tools such as Instruments and Swift Concurrency we will drastically reduce your app's start time while improving performance. Remember, the milliseconds are counted when engaging your users and providing their much desired satisfaction.
In depth profiling, bottleneck analysis and gradual optimization Implementations lead to smooth, high speed application launching.
Ready to transform your business with our technology solutions? Contact Us today to Leverage Our iOS Expertise.
0