Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS RUM - View LoadingTime not tracked #1114

Open
alexanderthoren opened this issue Jan 5, 2023 · 4 comments
Open

iOS RUM - View LoadingTime not tracked #1114

alexanderthoren opened this issue Jan 5, 2023 · 4 comments
Assignees

Comments

@alexanderthoren
Copy link

We are currently using Datadog v1.12.0 in iOS with SPM.

In Android we can access the parameter LoadingTime as it is sent to Datadog automatically. In iOS we are not able to track this automatically, and we found out that the class RUMViewScope in the function sendViewUpdateEvent always sends this parameter as nil.

I am attaching two screenshots, the first one from Android and the second one for iOS.

Screenshot 2023-01-05 at 18 01 31

Screenshot 2023-01-05 at 18 01 11

When this will be added to iOS? Is it scheduled for one of the next updates? Thanks! 😄

@maxep maxep self-assigned this Jan 6, 2023
@maxep
Copy link
Member

maxep commented Jan 6, 2023

Hey @alexanderthoren 👋

Indeed, there is no tracking of view loading time on iOS. The reason being that there is no strict definition of when it starts and when it stops. We are not sure what a view loading time would mean for View Controller, or for SwiftUI.View.

Maybe you could share your use case and we could think of a solution? How do you leverage this value on Android?

@alexanderthoren
Copy link
Author

Hello @maxep,

image

In the graph above we can see that when the system function viewDidAppear is called, the view is actually loaded, or at least presented to the user. We could start a timer on the init function and stop it in viewDidAppear to collect that LoadingTime. What do you think about this approach? 🤔

In Android, in onCreate function the timer is started and it stops in the onPause function. Then fun updateViewLoadingTime(key: Any, loadingTimeInNs: Long, type: ViewEvent.LoadingType) is called.

@ncreated
Copy link
Member

Hello @alexanderthoren 👋, thank you for more insights. To give you more background, the idea of view.loading_time originated in our Browser SDK and Monitoring Web Page Performance:

view.loading_time - Time until the page is ready and no network request or DOM mutation is currently happening.

In web world, this is very valuable metric indicating How long the user has to wait until all content is ready (on a web page)?. It clearly defines its purpose as different teams can work on optimising website resources, scripts, DOM and othear means to make this initial experience arrive earlier (hence they measure and aim at reducing the view.loading_time).

Measuring UIViewController.init() to .viewDidAppear() won't serve similar purpose because such measurement is detached from content being "ready" for the end user. Think for example of a screen that loads gallery of remote images - it might take several seconds until all images are shown to the user, but init() to .viewDidAppear() will most likely report 0.2s which is default duration in VCs transition. Even if images are not remote, but loaded from local bundle, the measurement won't tell anything about their overall loading performance as viewDidAppear() doesn't await for anything app-specific.

With lack of clear definition for "view loading time" on iOS, we rather promote the API for adding your own performance timing. It can be used to mark the end of app-specific routines, e.g. "all images loaded" or "UI is ready for interaction".

@MaelNamNam
Copy link
Contributor

Hi @alexanderthoren 👋

Following up on this, we picked this project up and recently delivered the first milestone: an experimental API to track the @view.loading_time telemetry in RUM. The docs can be found here for iOS (and there for Android if you were interested too by the way). It's still a manually instrumented solution as each View has its own business logic and it's (almost) impossible to reliably determine it's loading time from our end.

But there is much more to it than this declarative API. In parallel, we’re implementing 3 additional and out-of-the-box (read 'automated') timings. Names might change, we’re open to suggestions:

  1. Time to settled → the time it takes for the network requests that are part of the initial view load (either the ones happening in the first 𝑥 milliseconds, or the ones you’d flag manually) to be done
  2. Time to rendered → the time between the last user interaction on the previous view, and the end of some lifecycle event on the new one (e.g. viewDidAppear for UIKit and onAppear(perform:) for SwiftUI)
  3. Time to interacted → the time between the view starts being picked up by our SDK, and the first interaction from the user

For all of these timings that would be attached to the view event on RUM, we’re looking at an additional opt-in API to auto-instrument corresponding APM spans, so you could further expand the traces with more manually created spans, and break down these timings into actionable profiles.

To start with, would you be willing to give the manual API a try?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants