Drag pickup: evaluate a lane's slots once per body, not once per card

The per-element .accessibilitySortPriority read slots.count from inside the
ForEach closure, re-running the whole slots -> renderedCards chain (an O(n)
card filter plus the session's hidden-member resolution) once per element --
O(n^2) per lane body. A drag pickup runs a synchronous whole-board layout
inside the drag-start nested run loop, which multiplied this into a stack-
sampled ~700ms-1s stall between mouse-down and the visible lift. Hoisting
the evaluation into a local makes pickup effectively immediate.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-31 07:17:50 -04:00
parent 015e539b51
commit 95133860e1
+7 -1
View File
@@ -657,7 +657,13 @@ struct LaneView: View {
} }
private var scrollableCards: some View { private var scrollableCards: some View {
ScrollView(.vertical) { // Evaluated ONCE per body, deliberately: the per-element `.accessibilitySortPriority`
// below reads `slots.count`, and reading the computed property from inside the `ForEach`
// closure re-runs the whole chain (`slots` `renderedCards` the O(n) card filter and
// the session's hidden-member resolution) once per element O(n²) per lane body, which
// a drag pickup's synchronous whole-board layout multiplied into a visible stall.
let slots = self.slots
return ScrollView(.vertical) {
// Cards stay standard width whatever the lane spans: at a slot width of // Cards stay standard width whatever the lane spans: at a slot width of
// `units × standard + (units - 1) × gap`, `MasonryLayout` divides back into exactly // `units × standard + (units - 1) × gap`, `MasonryLayout` divides back into exactly
// `units` columns of `standard` (03-board-ui.md § Layout full visibility). // `units` columns of `standard` (03-board-ui.md § Layout full visibility).