perf: reduce SwiftUI update cascade during scroll#1
Draft
alex-duckmanton wants to merge 7 commits intomainfrom
Draft
perf: reduce SwiftUI update cascade during scroll#1alex-duckmanton wants to merge 7 commits intomainfrom
alex-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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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