EXPEDIA GROUP TECHNOLOGY — SOFTWARE

Monitoring App Performance on iOS

A guide to metrics and tools in the Apple app performance ecosystem

Corbin Montague
Mar 23 · 9 min read
the back of an iPhone
the back of an iPhone
Photo by Aleksander Vlad on Unsplash

Why monitor app performance?

Customers expect apps to perform well. An app that takes a long time to launch, or responds slowly to input, may appear to the user as if it’s not working or is sluggish. An app that makes a lot of large network requests may increase the user’s data charges and drain the device battery. Any of these behaviors can frustrate users and lead them to uninstall the app.

decorative separator
decorative separator

What metrics should you monitor?

App Size

  1. The time it takes for users to download and install your app.
  2. The method in which users are able to download your app (Cellular or WiFi).
  3. The hard drive space consumed by keeping your app installed on a user’s device.
  4. The finances of your users depending on the size of your app, the method in which then downloaded it, and their cellular plan.

Apple documents how you can reduce your app’s size.

App Launch Time

  • Cold — Occurs after a device reboot or when the app is not loaded in memory.
  • Warm — Occurs when the app was recently terminated or is partially loaded in memory.
  • Resume — Occurs when the app was suspended and is still fully loaded in memory.

The operating system significantly optimizes warm launches and resumes, so our focus should be cold launches which are the longest of the three. A cold launch is also the experience first time users will have with your app and we want to make a great first impression! In a 2019 WWDC talk, Apple presses developers to strive for a 400ms cold app launch where the cold launch breaks down as follows:

  1. For the first 100ms, iOS will do necessary system-side work in order to initialize your app.
  2. Over the next 300ms, you should create your views, load your content, and generate your first frame (with placeholders if necessary).
  3. After the initial 400ms, your app should be launched and interactable. It’s ok to continue loading additional content afterwards to replace any placeholder views in your initial frame.

Apple also documents details on how you can reduce your app’s launch time.

App Responsiveness

An app that responds instantly to users’ interactions gives an impression of supporting their workflow. When the app responds to gestures and taps in real time, it creates an experience for users that they’re directly manipulating the objects on the screen. An app that doesn’t respond within a short time shatters this illusion, and leaves users wondering whether the app works correctly at all.

The human perception system is adept at identifying motion, and linking cause to effect through sequential actions. It doesn’t take long for a person to observe a gap between two events as a pause. Users can form the impression that an app is inert and unresponsive after a delay as short as a few tenths of a second. Apps therefore have to react to a user’s actions very quickly to maintain the user’s confidence in their behavior.

Monitoring app responsiveness can involve looking at a number of different metrics, most notably:

  • View load times
  • View update times
  • Scroll hitch rate
  • App hangs

Memory Usage

You can reduce your app’s memory use by following Apple’s guidance.

Battery Usage

Apple has a collection of WWDC talks and articles on how to debug and write energy efficient apps.

Network Performance

  • The number of network requests sent by your app
  • The speed or round-trip time (RTT) of each network request
  • The amount of data requested by each network request

While the speed of network requests determines how quickly you can retrieve the data necessary to populate your view’s content during a load or update, the number of requests and amount of data requested can incur costs on your users who lack an unlimited data plan and likely affect your company’s finances as well.

There is a great 2020 WWDC talk on how you can boost both network performance and security in your app.

Disk I/O

Again, Apple documents strategies to reduce disk writes in your app.

decorative separator
decorative separator

What native iOS tools are available to automate monitoring these metrics?

XCTest Metrics

screenshot of code measure{ XCUIApplication().launch() }
screenshot of code measure{ XCUIApplication().launch() }

See Apple documentation here and this 2019 WWDC talk for details on using XCTest APIs for measuring app performance metrics within your unit and UI tests.

MetricKit

First you’ll need to declare an NSObject class that conforms to the MXMetricManagerSubscriber protocol:

import MetricKit
import os.log
/// A concrete implementation of `MXMetricManagerSubscriber` that listens for and processes daily app metrics.
class AppMetricManager: NSObject, MXMetricManagerSubscriber {

// MARK: - Dependencies

let metricManager: MXMetricManager

// MARK: - Init/Deinit

init(metricManager: MXMetricManager = MXMetricManager.shared) {
self.metricManager = metricManager

super.init()

// subscribe to receive metrics
metricManager.add(self)
}

deinit {
metricManager.remove(self)
}

// MARK: - MXMetricManagerSubscriber

// called at most once every 24hrs with daily app metrics
func didReceive(_ payloads: [MXMetricPayload]) {
os_log("Received Daily MXMetricPayload:", type: .debug)
for metricPayload in payloads {
if let metricPayloadJsonString = String(data: metricPayload.jsonRepresentation(), encoding: .utf8) {
os_log("%@", type: .debug, metricPayloadJsonString)

// Here you could upload these metrics (in JSON form) to your servers to aggregate app performance metrics
}
}
}

// called at most once every 24hrs with daily app diagnostics
@available(iOS 14.0, *)
func didReceive(_ payloads: [MXDiagnosticPayload]) {
os_log("Received Daily MXDiagnosticPayload:", type: .debug)
for diagnosticPayload in payloads {
if let diagnosticPayloadJsonString = String(data: diagnosticPayload.jsonRepresentation(), encoding: .utf8) {
os_log("%@", type: .debug, diagnosticPayloadJsonString)

// Here you could upload these metrics (in JSON form) to your servers to aggregate app performance metrics
}
}
}
}

Then, in your AppDelegate:

class AppDelegate: UIResponder, UIApplicationDelegate, MXMetricManagerSubscriber {

private var appMetricManager: AppMetricManager?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
appMetricManager = AppMetricManager()

return true
}

}

And 💥… that’s it! Your AppMetricManager will get a callback about once every 24 hours with battery and performance metrics. Here you can transform the data and upload it to your own servers if you have internal dashboards for monitoring analytics around your app’s performance metrics.

See Apple documentation here and this 2020 WWDC talk for details on how you can use MetricKit to monitor app performance metrics for your TestFlight and AppStore users.

Xcode Metrics Organizer

screenshot of battery usage histograms broken into categories audio, networking, processing, display, other
screenshot of battery usage histograms broken into categories audio, networking, processing, display, other

See Apple documentation here and this 2020 WWDC talk for details on analyzing the performance of your app within Xcode Organizer.

decorative separator
decorative separator

What third party tools are available to monitor these metrics?

Firebase Performance

See Google documentation here for details on how you can setup Firebase Performance in your iOS app.

SwiftInfo

You can find the Github repo for this library here.

Summary

Expedia Group Technology

Stories from the Expedia Group Technology teams

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store