Platform disparity issue: update-time tracking works on Core, React, and Android — iOS is the only platform where it cannot be implemented today.
Core, React, and Android MetricsPlugin all support trackUpdateTime — timing updates to an already-rendered view. iOS only supports trackRenderTime (first paint). This is not an unimplemented feature — it's a fundamental SwiftUI API gap with no known workaround.
Investigation ruled out three approaches:
-
.onAppear — view identity is intentionally kept stable across in-place updates (SwiftUIPlayer.swift), so it only fires once per view, never again on update.
-
Forcing view identity to change to retrigger .onAppear — would work mechanically, but causes unacceptable UI side effects (unwanted transitions/animation churn).
-
A custom onRender-style view modifier firing inline during body evaluation — fires before SwiftUI diffs, lays out, or paints anything, so it measures "time until body re-ran," not "time until the screen updated." Can also fire for reasons unrelated to the update being tracked. Concluded to basically always record a false time, not just an imprecise one.
-
.onChange — same category of limitation, no access to real paint completion.
Platform disparity issue: update-time tracking works on Core, React, and Android — iOS is the only platform where it cannot be implemented today.
Core, React, and Android MetricsPlugin all support trackUpdateTime — timing updates to an already-rendered view. iOS only supports trackRenderTime (first paint). This is not an unimplemented feature — it's a fundamental SwiftUI API gap with no known workaround.
Investigation ruled out three approaches:
.onAppear — view identity is intentionally kept stable across in-place updates (SwiftUIPlayer.swift), so it only fires once per view, never again on update.
Forcing view identity to change to retrigger .onAppear — would work mechanically, but causes unacceptable UI side effects (unwanted transitions/animation churn).
A custom onRender-style view modifier firing inline during body evaluation — fires before SwiftUI diffs, lays out, or paints anything, so it measures "time until body re-ran," not "time until the screen updated." Can also fire for reasons unrelated to the update being tracked. Concluded to basically always record a false time, not just an imprecise one.
.onChange — same category of limitation, no access to real paint completion.