perf: reduce SwiftUI update cascade during scroll#1
perf: reduce SwiftUI update cascade during scroll#1alex-duckmanton wants to merge 7 commits intomainfrom
Conversation
On iOS, tapping a non-URL area while text is selected does nothing — the selection persists until the user double-taps another word. The macOS equivalent (mouseDown) correctly calls resetSelection(). Clear model.selectedRange on non-URL taps to match macOS behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Skip redundant @State writes in BlockLayoutView.onPreferenceChange when the resolved block spacing value hasn't changed. Eliminates ~295K unnecessary SwiftUI state invalidations during scroll. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Track currentAttachmentSizes with @ObservationIgnored and skip sizeChanged when the computed sizes match. Eliminates ~204K redundant @observable mutations during scroll that cascaded into TextFragment body re-evaluations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Skip redundant @State writes when the resolved AttributedString output hasn't changed. Eliminates ~162K unnecessary state invalidations that cascaded into TextFragment rebuilds during scroll. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Skip redundant @State writes when the marker width preference value hasn't changed. Prevents cascading preference updates in ordered lists during scroll. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace separate AttachmentOverlay + TextLinkInteraction modifiers with a single TextFragmentOverlay that uses one overlayPreferenceValue subscription and one GeometryReader per text fragment instead of two of each. This halves the GeometryReader count and should significantly reduce the update cascade during scrolling (72K SecondaryChild updates in trace). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These modifiers were superseded by the consolidated TextFragmentOverlay. Updates stale comments in TextFragment, TextBuilder, and System Overview to reference the new modifier. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Review NotesReviewed the diff and investigated three areas in detail: 1. swiftui-math in Package.resolvedNot introduced by this PR — it's declared in 2. WithInlineStyle AttributedString equality (line 81)
3. TextBuilder dictionary equality (
|
Summary
@Statewrites inBlockSpacing,TextBuilder,WithInlineStyle.output, andOrderedList.markerWidth— prevents redundant state mutations that trigger unnecessary view re-evaluations during scrollingoverlayPreferenceValue+GeometryReaderpairs (fromAttachmentOverlayandTextLinkInteraction) into a singleTextFragmentOverlaymodifier, halving the GeometryReader count per text fragmentTraced on iPhone 15 Pro in a long conversation (31 meeting summaries with nested markdown). Before these changes: 1.8M SwiftUI updates with a 543ms hang. The
SecondaryChild<Text.LayoutKey, GeometryReader?>alone accounted for 72K updates.Test plan
🤖 Generated with Claude Code