Here's a simple tip that might drastically improve your app performance: don't block your app launch.
i.e. when you implement
application(_:didFinishLaunchingWithOptions:) or related methods in
UIApplicationDelegate such as
application(_:willFinishLaunchingWithOptions:), don't perform operations in them that run synchronously in the main thread. Naturally, running long operations in your app delegate on the main thread blocks your app from launching/resuming. It can be overlooked though. For example, when you implement and perform data migration when your app launches. Initially this might be an immediate operation. But as you go along and the app's data model become more complex and the user accumulates more data, a simple data migration might take too long and causes the app launch to be noticeably slower. This is not only poor user experience — a slow app launch can cause iOS to kill your app.
The same principle applies to methods such as