Skip to content

Commit 0ef169e

Browse files
committed
chore(apple): Add docs for SwiftUI TTID/TTFD
1 parent edbd361 commit 0ef169e

File tree

4 files changed

+130
-13
lines changed

4 files changed

+130
-13
lines changed

docs/platforms/apple/common/tracing/instrumentation/automatic-instrumentation.mdx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -447,12 +447,6 @@ When the user interaction transaction is not finished yet, but the user makes a
447447

448448
## Time to Initial Display
449449

450-
<Alert>
451-
452-
This feature only works for UIViewControllers and not for SwiftUI.
453-
454-
</Alert>
455-
456450
By adding a span for a view controller when it's loaded, time to initial display (TTID) provides insight into how long it takes for your view controller to launch and draw its first UI frame. The SDK sets the span operation to `ui.load.initial-display` and the span description to the view controller's name, followed by `initial display` - for example, `MainViewController initial display`.
457451

458452
The span starts when the view of a view controller is loaded, and there is no other view controller transaction happening at the moment. The span finishes after the view appeared on the screen. The following chart shows how time to initial display (TTID) and [time to full display (TTFD)](#time-to-full-display) correlate to transitions between activities:
@@ -461,18 +455,24 @@ The span starts when the view of a view controller is loaded, and there is no ot
461455

462456
Since Cocoa SDK version 8.33.0, the SDK doesn't create time to initial display (TTID) and [time to full display (TTFD)](#time-to-full-display) spans for UIViewControllers presented in the background because the logic requires UI frames to be drawn.
463457

464-
## Time to Full Display
465-
466458
<Alert>
467459

468-
This feature only works for UIViewControllers and not for SwiftUI.
460+
For SwiftUI views, see the [SwiftUI Instrumentation documentation](/platforms/apple/common/tracing/instrumentation/swiftui-instrumentation/#time-to-initial-display-and-time-to-full-display) for TTID and TTFD tracking.
469461

470462
</Alert>
471463

472-
By adding a span for a view controller when it's loaded, time to full display (TTFD) provides insight into how long it takes your view controller to launch and load all of its content. The span starts when the view of a view controller is loaded, and there is no other view controller transaction happening at the moment. The SDK sets the span operation to `ui.load.full-display` and the span description to the view controllers' name, followed by `full display` - for example, `MainActivity full display`.
464+
## Time to Full Display
465+
466+
By adding a span for a view controller when it's loaded, time to full display (TTFD) provides insight into how long it takes your view controller to launch and load all of its content. The span starts when the view of a view controller is loaded, and there is no other view controller transaction happening at the moment. The SDK sets the span operation to `ui.load.full-display` and the span description to the view controllers' name, followed by `full display` - for example, `MainViewController full display`.
473467

474468
Since Cocoa SDK version 8.33.0, the SDK doesn't create [time to initial display (TTID)](#time-to-initial-display) and time to full display (TTFD) spans for UIViewControllers presented in the background, because the logic requires UI frames to be drawn.
475469

470+
<Alert>
471+
472+
For SwiftUI views, see the [SwiftUI Instrumentation documentation](/platforms/apple/common/tracing/instrumentation/swiftui-instrumentation/#time-to-initial-display-and-time-to-full-display) for TTID and TTFD tracking.
473+
474+
</Alert>
475+
476476
_Time to full display is disabled by default, but you can enable it by setting:_
477477

478478
```swift {tabTitle:Swift}

docs/platforms/apple/common/tracing/instrumentation/swiftui-instrumentation.mdx

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,117 @@ var body: some View {
8080
This is the result
8181

8282
![Transaction with nested traced views](./img/nested-view-transaction.png)
83+
84+
## Time to Initial Display and Time to Full Display
85+
86+
<Alert>
87+
88+
This feature is available since version 8.44.0 and only works for iOS and tvOS.
89+
90+
</Alert>
91+
92+
You can track time to initial display (TTID) and time to full display (TTFD) for your SwiftUI views to measure how long it takes for screens to render their first frame and then fully load all content.
93+
94+
- **Time to initial display (TTID)**: Automatically tracked when the view appears on screen. The SDK sets the span operation to `ui.load.initial-display` and the span description to the view name followed by `initial display` - for example, `Content View Body initial display`.
95+
96+
- **Time to full display (TTFD)**: Requires enabling with the `waitForFullDisplay` parameter and manually calling `SentrySDK.reportFullyDisplayed()` when your view has finished loading all content. The SDK sets the span operation to `ui.load.full-display` and the span description to the view name followed by `full display` - for example, `Content View Body full display`.
97+
98+
### Enabling Time to Full Display
99+
100+
To enable TTFD tracking, set `waitForFullDisplay: true` when creating a `SentryTracedView`:
101+
102+
```swift {tabTitle:Swift}
103+
104+
import SentrySwiftUI
105+
import Sentry
106+
107+
var body: some View {
108+
SentryTracedView("Content View Body", waitForFullDisplay: true) {
109+
VStack {
110+
// Your SwiftUI content
111+
}
112+
.onAppear {
113+
// Load async content, then call:
114+
SentrySDK.reportFullyDisplayed()
115+
}
116+
}
117+
}
118+
```
119+
120+
Alternatively, you can use the `sentryTrace` modifier with `waitForFullDisplay: true`:
121+
122+
```swift {tabTitle:Swift}
123+
124+
import SentrySwiftUI
125+
import Sentry
126+
127+
var body: some View {
128+
VStack {
129+
// Your SwiftUI content
130+
}
131+
.sentryTrace("Content View Body", waitForFullDisplay: true)
132+
.onAppear {
133+
// Load async content, then call:
134+
SentrySDK.reportFullyDisplayed()
135+
}
136+
}
137+
```
138+
139+
If you don't specify `waitForFullDisplay`, the SDK will use the value from the `enableTimeToFullDisplayTracing` option. You can enable TTFD globally for all views by setting this option:
140+
141+
```swift {tabTitle:Swift}
142+
143+
import Sentry
144+
145+
SentrySDK.start { options in
146+
options.dsn = "___PUBLIC_DSN___"
147+
options.enableTimeToFullDisplayTracing = true
148+
}
149+
```
150+
151+
### When to Call reportFullyDisplayed()
152+
153+
Call `SentrySDK.reportFullyDisplayed()` when your view has finished loading all of its content, including any asynchronous operations like:
154+
155+
- Network requests to fetch data
156+
- Image loading
157+
- Database queries
158+
- Any other async operations that affect the view's content
159+
160+
Typically, you'll call this in the `onAppear` modifier after your async content has loaded:
161+
162+
```swift {tabTitle:Swift}
163+
164+
import SentrySwiftUI
165+
import Sentry
166+
167+
struct ContentView: View {
168+
@State private var data: [Item] = []
169+
170+
var body: some View {
171+
SentryTracedView("Content View", waitForFullDisplay: true) {
172+
List(data) { item in
173+
Text(item.title)
174+
}
175+
.onAppear {
176+
Task {
177+
// Load data asynchronously
178+
data = await loadData()
179+
// Report when fully displayed
180+
SentrySDK.reportFullyDisplayed()
181+
}
182+
}
183+
}
184+
}
185+
}
186+
```
187+
188+
### Important Notes
189+
190+
- **Nested views**: The `waitForFullDisplay` parameter is ignored for nested `SentryTracedView` instances. Only the root transaction (the outermost `SentryTracedView`) will track TTID and TTFD spans.
191+
192+
- **30-second timeout**: If `reportFullyDisplayed()` is not called within 30 seconds, the TTFD span will automatically finish with `SpanStatus.DEADLINE_EXCEEDED`. The duration will match the TTID span duration, and the description will contain a `Deadline Exceeded` suffix.
193+
194+
- **Early calls**: If `reportFullyDisplayed()` is called before the view appears, the reported time will be shifted to match the TTID measured time.
195+
196+
For more information about TTID and TTFD metrics, see the [Mobile Vitals documentation](/product/insights/mobile/mobile-vitals/#time-to-initial-display-and-time-to-full-display).

docs/product/insights/mobile/mobile-vitals/index.mdx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,16 @@ In the example below, the detail view of the transaction displays the time-to-in
9090
You can track time to initial display for:
9191

9292
- [Android](/platforms/android/tracing/instrumentation/automatic-instrumentation/#time-to-initial-display)
93-
- [Apple](/platforms/apple/tracing/instrumentation/automatic-instrumentation/#time-to-initial-display)
93+
- [Apple UIViewController](/platforms/apple/tracing/instrumentation/automatic-instrumentation/#time-to-initial-display)
94+
- [Apple SwiftUI](/platforms/apple/common/tracing/instrumentation/swiftui-instrumentation/#time-to-initial-display-and-time-to-full-display) (since 8.44.0)
9495
- [Flutter](/platforms/dart/guides/flutter/integrations/routing-instrumentation/#time-to-initial-display)
9596
- [React Native](/platforms/react-native/performance/instrumentation/time-to-display/#automatic-time-to-initial-display-for-react-navigation)
9697

9798
You can track time to full display for:
9899

99100
- [Android](/platforms/android/tracing/instrumentation/automatic-instrumentation/#time-to-full-display)
100-
- [Apple](/platforms/apple/tracing/instrumentation/automatic-instrumentation/#time-to-full-display)
101+
- [Apple UIViewController](/platforms/apple/tracing/instrumentation/automatic-instrumentation/#time-to-full-display)
102+
- [Apple SwiftUI](/platforms/apple/common/tracing/instrumentation/swiftui-instrumentation/#time-to-initial-display-and-time-to-full-display) (since 8.44.0)
101103
- [Flutter](/platforms/dart/guides/flutter/integrations/routing-instrumentation/#time-to-full-display)
102104
- [React Native](/platforms/react-native/performance/instrumentation/time-to-display/#time-to-full-display)
103105

docs/product/insights/mobile/mobile-vitals/screen-loads.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ Sentry tracks TTID automatically, but [TTFD](/product/insights/mobile/mobile-vit
2525
**For iOS:**
2626

2727
- `>=7.12.0` for UIViewController transactions
28-
- `>=8.4.0` for [TTID](/platforms/apple/guides/ios/tracing/instrumentation/automatic-instrumentation/#time-to-initial-display)+[TTFD](/platforms/apple/guides/ios/tracing/instrumentation/automatic-instrumentation/#time-to-full-display)
28+
- `>=8.4.0` for [TTID](/platforms/apple/guides/ios/tracing/instrumentation/automatic-instrumentation/#time-to-initial-display)+[TTFD](/platforms/apple/guides/ios/tracing/instrumentation/automatic-instrumentation/#time-to-full-display) for UIViewController
29+
- `>=8.44.0` for [TTID+TTFD for SwiftUI](/platforms/apple/common/tracing/instrumentation/swiftui-instrumentation/#time-to-initial-display-and-time-to-full-display)
2930

3031
**For Flutter:**
3132

0 commit comments

Comments
 (0)