perf: replace .move(edge: .bottom) transitions with .opacity in LazyVStack to fix motionVectors hang (LUM-795)#24375
Merged
ashleeradka merged 2 commits intoApr 8, 2026
Conversation
…Stack to fix motionVectors hang (LUM-795) Co-Authored-By: ashlee@vellum.ai <ashlee@vellum.ai>
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…line warning Co-Authored-By: ashlee@vellum.ai <ashlee@vellum.ai>
ashleeradka
approved these changes
Apr 8, 2026
noanflaherty
pushed a commit
that referenced
this pull request
Apr 8, 2026
…Stack to fix motionVectors hang (LUM-795) (#24375) * perf: replace .move(edge: .bottom) transitions with .opacity in LazyVStack to fix motionVectors hang (LUM-795) Co-Authored-By: ashlee@vellum.ai <ashlee@vellum.ai> * docs: add LazyVStack transition anti-pattern rule to AGENTS.md and inline warning Co-Authored-By: ashlee@vellum.ai <ashlee@vellum.ai> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: ashlee@vellum.ai <ashlee@vellum.ai>
2 tasks
Jasonnnz
pushed a commit
that referenced
this pull request
Apr 10, 2026
Adds CI-enforced guard tests that scan Swift source files for three known LazyVStack performance anti-patterns: 1. FlexFrameLayout (.frame(maxWidth:) / .frame(maxHeight:)) in cell hierarchy 2. motionVectors transitions (.transition(.move(edge:))) in cell hierarchy 3. withAnimation in scroll handlers (motionVectors cascade) Prevents regression of fixes from PRs #24321, #24375, #24411, #24446, #24530, #24570, #24589. Part of #24613. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3 tasks
Jasonnnz
added a commit
that referenced
this pull request
Apr 10, 2026
* test: add SwiftUI performance guard tests for LazyVStack anti-patterns Adds CI-enforced guard tests that scan Swift source files for three known LazyVStack performance anti-patterns: 1. FlexFrameLayout (.frame(maxWidth:) / .frame(maxHeight:)) in cell hierarchy 2. motionVectors transitions (.transition(.move(edge:))) in cell hierarchy 3. withAnimation in scroll handlers (motionVectors cascade) Prevents regression of fixes from PRs #24321, #24375, #24411, #24446, #24530, #24570, #24589. Part of #24613. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add missing cell files to LAZY_VSTACK_CELL_FILES and remove PR references Adds the 10 allowlisted file basenames to the cell hierarchy list so the allowlist is actually consulted. Removes historical PR numbers from the file header comment per AGENTS.md guidance. Co-Authored-By: Claude <noreply@anthropic.com> * fix: use grep -E for portable ERE alternation in FlexFrame guard BSD grep (macOS default) doesn't support \| in BRE mode. Switch to grep -E with | for alternation so the guard works for local dev too. Co-Authored-By: Claude <noreply@anthropic.com> * fix: add SubagentEventsReader to cell files and escape dots in transition grep Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Vellum Assistant <assistant@vellum.ai> Co-authored-by: Claude Opus 4.6 (1M context) <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.
Replaces
.transition(.opacity.combined(with: .move(edge: .bottom)))with.transition(.opacity)on 4 items inside theLazyVStackinMessageListContentView.swift. The.move(edge: .bottom)component forces SwiftUI to compute the total content height of the LazyVStack duringmotionVectors→measureEstimates, iterating every ForEach child and defeating lazy loading — causing 100+ second main-thread hangs..opacityonly needs the view's own frame, so it's safe inside lazy containers. This is a follow-up to #24321 (LUM-740), which was necessary but insufficient.Also adds a permanent anti-pattern rule to
clients/macos/AGENTS.mdand an inline warning comment above the LazyVStack body to prevent reintroduction by future features copying old patterns.Review & Testing Checklist for Human
.move(edge:)transitions exist inside the LazyVStack body (the other.move(edge:)usages in the chat area are all in overlays outside the LazyVStack and are unaffected)Notes
.move(edge:)transitions in the codebase (ChatView overlays, ComposerView, error toasts, etc.) are not inside a LazyVStack and don't trigger the measurement issue — they are intentionally left unchangedLink to Devin session: https://app.devin.ai/sessions/d11994a0494e456ea259a789e3b41f6a
Requested by: @ashleeradka