Skip to content

Conversation

@naftaly
Copy link
Contributor

@naftaly naftaly commented May 5, 2025

SwiftUI View Instrumentation

This document states the current implementation of SwiftUI View tracing.

PR: #230

The render loop

On iOS, the system for getting anything from the users code to the screen is called the render loop. It consists of a few parts, some we have control over and others we don’t. The important part is that the render loop refresh rate is pre-determined, but can change at runtime based on the state of the device. Usually, it’s 60hz which ends up being 16ms, called the frame deadline. If we miss the frame deadline, we have what is called a hitch since the system needs to wait another frame to put our content on screen.

frame_deadline source: Apple

Embrace View Instrumentation

  • Render Loop: The duration from the first instrumented body in a render loop to the next tick of the run loop. This is a root trace.

    • name: emb-swiftui.view..render-loop
    • parent: none
    1. body: This is the duration it takes to setup the graph of what the OS will need to render.
      • name: emb-swiftui.view..body
      • parent: RenderLoop
    2. onAppear: The duration from the top of the callback to the next tick of the run loop.
      • name: emb-swiftui.view..appear
      • parent: RenderLoop
    3. onDisappear: The duration from the top of the callback to the next tick of the run loop.
      • name: emb-swiftui.view..disappear
      • parent: RenderLoop
  • Time To First Render: The duration from the first time the OS initializes this View until the first time it appears on screen. This is a root trace.

    • name: emb-swiftui.view..time-to-first-render
    • parent: none
  • Time To First Content Complete: The duration from the first time the OS initializes this View until the first time the user flags the content as complete. This is a root trace.

    • name: emb-swiftui.view..time-to-first-content-complete
    • parent: none
    • notes: Not available in the macro.

Example

Only the Photo surface is instrumented.

Session as a Gantt chart:

SwiftUI Performance Gantt Chart.pdf

Session in Embrace Dash:

https://dash.embrace.io/app/wnrhv/grouped_sessions/last_1_hour/54F35B20EF7C41F5ADC0668C1F34DA63/8192029933B74B9896ADD165F48C45A7@/8192029933B74B9896ADD165F48C45A7?first=9C393D0FBD3740E38DC28F60C4496358&last=2D3323E6C2FE479D867903D2C70BF2EB&source=session

API

Parameters:

  • name: Required. autodetected in macro.
  • attributes: Optional. key value pairs.
  • contentComplete: Optional. an Equatable value that when changed, will cause the time to first content complete span to end.

View Wrapper

struct MyView: View {

	@State
	var loaded: Bool = false

	var body: some View {
		EmbraceTraceView(
	    		"MyView", 
	    		attributes: [:], 
	    		contentComplete: loaded
			) {
        			Text("Hello World")
        			Button("FInish Load") {
            				loaded = true
        			}
    			}
		}
	}
}

View Modifier

struct MyView: View {
	@State
	var loaded: Bool = false

	var body: some View {
    		Group {
        		Text("Hello World")
        		Button("Finish Load") {
            			loaded = true
        		}
    		}
    		.embraceTrace("MyView", attributes: [:], contentComplete: loaded)
	}
}

Macro. At this time, the macro cannot take any arguments. We may allow this in the future.

@EmbraceTrace
struct MyView: View {
	var body: some View {
		Text("Hello World")
	}
}

@github-actions
Copy link

github-actions bot commented May 5, 2025

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 1 package(s) with unknown licenses.
See the Details below.

License Issues

Package.resolved

PackageVersionLicenseIssue Type
github.com/swiftlang/swift-syntax509.1.1NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
swift/github.com/swiftlang/swift-syntax 509.1.1 UnknownUnknown

Scanned Files

  • Package.resolved

@github-actions
Copy link

github-actions bot commented May 5, 2025

Warnings
⚠️ No CHANGELOG entry added.

Generated by 🚫 Danger Swift against 63929b6

@codecov
Copy link

codecov bot commented May 5, 2025

Codecov Report

Attention: Patch coverage is 76.80764% with 170 lines in your changes missing coverage. Please review.

Project coverage is 88.36%. Comparing base (1710885) to head (63929b6).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...rces/EmbraceMacros/Plugins/EmbraceTraceMacro.swift 0.00% 117 Missing ⚠️
Sources/EmbraceCore/SwiftUI/EmbraceTraceView.swift 87.68% 17 Missing ⚠️
...EmbraceCore/SwiftUI/EmbraceTraceViewModifier.swift 0.00% 13 Missing ⚠️
...eCore/SwiftUI/Internal/EmbraceTraceViewState.swift 40.00% 9 Missing ⚠️
...Core/SwiftUI/Internal/EmbraceTraceViewLogger.swift 92.75% 5 Missing ⚠️
Sources/EmbraceConfigInternal/EmbraceConfig.swift 0.00% 3 Missing ⚠️
...figInternal/EmbraceConfigurable/RemoteConfig.swift 0.00% 3 Missing ⚠️
...es/EmbraceMacros/Plugins/EmbraceMacrosPlugin.swift 0.00% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #230      +/-   ##
==========================================
- Coverage   88.75%   88.36%   -0.40%     
==========================================
  Files         448      458      +10     
  Lines       30513    31286     +773     
==========================================
+ Hits        27082    27646     +564     
- Misses       3431     3640     +209     
Files with missing lines Coverage Δ
...onfigurable/RemoteConfig/RemoteConfigPayload.swift 100.00% <100.00%> (ø)
...figuration/EmbraceConfigurable/DefaultConfig.swift 84.21% <100.00%> (+0.87%) ⬆️
...ore/SwiftUI/Internal/EmbraceTraceViewContext.swift 100.00% <100.00%> (ø)
...urable/RemoteConfig/RemoteConfigPayloadTests.swift 100.00% <100.00%> (ø)
...eCoreTests/SwiftUI/EmbraceTraceViewPerfTests.swift 100.00% <100.00%> (ø)
...braceCoreTests/SwiftUI/EmbraceTraceViewTests.swift 100.00% <100.00%> (ø)
Tests/EmbraceMacrosTests/EmbraceMacrosTests.swift 100.00% <100.00%> (ø)
Tests/TestSupport/EditableConfig.swift 90.00% <100.00%> (+0.71%) ⬆️
...ts/TestSupport/Mocks/MockEmbraceConfigurable.swift 55.75% <100.00%> (+3.82%) ⬆️
Sources/EmbraceConfigInternal/EmbraceConfig.swift 71.76% <0.00%> (-2.63%) ⬇️
... and 7 more

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@naftaly naftaly force-pushed the acohen/swiftui-view-tracing branch from 668c304 to 1154c25 Compare May 5, 2025 20:06
@naftaly naftaly force-pushed the acohen/swiftui-view-tracing branch 2 times, most recently from f8f3373 to 3f30d07 Compare May 12, 2025 16:43
@naftaly naftaly force-pushed the acohen/swiftui-view-tracing branch 2 times, most recently from 13e4e81 to 05315c9 Compare May 19, 2025 23:18
@naftaly naftaly requested a review from NachoEmbrace May 19, 2025 23:20
@naftaly naftaly marked this pull request as ready for review May 19, 2025 23:30
@naftaly naftaly requested a review from a team as a code owner May 19, 2025 23:30
@naftaly naftaly changed the title [WIP] SwiftUI View Tracing SwiftUI View Tracing May 19, 2025
@naftaly naftaly force-pushed the acohen/swiftui-view-tracing branch from 011c9e6 to 7137ba5 Compare May 21, 2025 21:49
@naftaly naftaly force-pushed the acohen/swiftui-view-tracing branch 2 times, most recently from 4db1532 to 0ebdc70 Compare June 3, 2025 22:34
@naftaly naftaly requested a review from ArielDemarco June 3, 2025 22:35
@naftaly naftaly force-pushed the acohen/swiftui-view-tracing branch from 2c9f70d to f1e8fa9 Compare June 6, 2025 17:27
@naftaly naftaly force-pushed the acohen/swiftui-view-tracing branch 2 times, most recently from 9674722 to 8d2f63c Compare June 16, 2025 18:58
@naftaly naftaly force-pushed the acohen/swiftui-view-tracing branch from 55c7aa0 to 1c7281f Compare June 19, 2025 15:35
@naftaly naftaly force-pushed the acohen/swiftui-view-tracing branch from 1c7281f to 2feaa94 Compare June 23, 2025 22:31
@naftaly naftaly merged commit e7e708f into main Jun 24, 2025
10 checks passed
@naftaly naftaly deleted the acohen/swiftui-view-tracing branch June 24, 2025 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants