Skip to content
Gleb edited this page Jun 28, 2023 · 4 revisions

Time to Interactive (TTI)

Time to interactive (TTI) is a time in milliseconds (ms) spent since the screen's creation starts until the first frame of meaningful content is rendered, ensuring that:

  • All internal setup is ready
  • UI is layout and rendered
  • Most important data has arrived and is shown to user
  • Main thread is ready to process incoming events

TTI always includes native app performance, and also may depend on the network performance. This metrics allow us to monitor how fast user can actually start using the screen in its main purpose.

See also:

Time To First Render (TTFR)

Time To First Render (TTFR) is a time in milliseconds (ms) spent since the screen's creation starts until the screen renders its first frame.

It starts at the same time as general TTI measurement, but may stop earlier. In the most common case screen should be ready to be drawn as soon as possible, but it shouldn't necessarily show meaningful content immediately. Usually screen can show some "pre-loader" and do some heavy initializations in the background. We stop TTFR tracking once the very first frame is drawn so the metric is pretty close to measuring screen's creation time. It allows us to prevent UI thread from freezing on creation which comes with better user experience.

This metric directly impacts TTI and may impact Rendering Performance.

TTI

Implementation

Implement TTIMetricsReceiver to receive TTI events for your view controllers.

If you track TTI for your screen: explicitly call screenIsReady() in your view controller when it is completely usable (data loaded and displayed). If you do not call this method, screen is considered usable by default after viewDidAppear is called.

The moment of the screen becoming usable should be wisely defined by the developer.

Also, it is always important to carefully maintain the correctness of TTI tracking on the client (e.g. when screen's UI/UX is changed, or refactoring made, or any changes made in screen's initialization process).

SwiftUI support

If you screen is purely on SwiftUI you usually still have your own subclass of UIHostingController. If you can't call screenIsReady method from the view controller, because you don't have the reference to the view controller from your SwiftUI view, you can use screenIsReadyOnAppear extension in your SwiftUI view:

    var body: some View {
      if viewModel.isLoading {
        ProgressView()
      } else {
        Text("Screen is ready").screenIsReadyOnAppear()
      }
    }

Fragments TTI tracking

All TTI tracking works on the UIViewController level. If you want to track TTI for some part of code without corresponding UIViewController, for example for a separate banner or a separate row of the screen, you can use fragment TTI tracking. This works manually: you call PerformanceMonitoring.startFragmentTTI(screen:), which returns you an object. And when ready, you call method fragmentIsRendered to stop TTFR (not mandatory) and fragmentIsReady to stop TTI.

self.trackable = try? PerformanceMonitoring.startFragmentTTI(screen: .geniusVipFragmentBookingDetails)
...
if hasDataToShow {
  self.trackable?.fragmentIsReady()
}
Clone this wiki locally