Fix drag-and-drop memory leak and reordering with variable item heights#1
Open
AustinMKerr wants to merge 3 commits into
Open
Fix drag-and-drop memory leak and reordering with variable item heights#1AustinMKerr wants to merge 3 commits into
AustinMKerr wants to merge 3 commits into
Conversation
…m heights Two issues in the dynamic-height drag-and-drop path: - Memory leak: computeItemHeightArray() logged its result object (and a "Document not found" string) on every dragover event, which fires continuously during a drag. Objects passed to console.log are retained by the browser console heap and can never be GC'd, so memory grew unbounded for the duration of each drag. Removed the hot-path logging. - Reordering didn't track when items have different sizes: the cumulative- height loop only assigned linearIndex/hoveringPosition when the pointer fell within an item, so dragging below the last item (into the tree's empty space) left both at 0 and snapped the drop indicator to the top. Rewrote it to compute a fractional linear index from each item's measured height, clamp linearIndex against the real linear-item list, and treat "below the last item" as past-the-end so the bottom-drop offset resolves correctly. Removed dead commented-out code left from the WIP. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtzjXm3E3o416rYjqWzEqv
- Use `i += 1` instead of `i++` in the hovering-position loop (airbnb no-plusplus) and hoist the loop condition into a named variable to keep lines within the 80-col prettier limit. - Drop the now-unused `itemHeight` from DragBetweenLine's destructure (it was left over when the line offset switched to itemsHeightArray) and extract the summed-height offset into a `lineOffset` variable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtzjXm3E3o416rYjqWzEqv
…eights The dynamic-height refactor switched the drag math to computeItemHeightArray, but the test harness only mocked computeItemHeight. Under the auto-mocked layoutUtils module, computeItemHeightArray returned undefined, so reading its .length threw and every drag-and-drop test failed. Mock it to return uniform 10px heights (matching dragOver's clientY math of itemIndex * 10 + offset). With uniform heights the cumulative-height calculation is mathematically identical to the previous clientY / itemHeight formula, so behavior is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtzjXm3E3o416rYjqWzEqv
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
Fixes two issues in the dynamic item-height drag-and-drop path that were introduced alongside the
itemsHeightArrayrefactor.1. Memory leak during drag
computeItemHeightArray()calledconsole.log({ itemHeights })(andconsole.log("Document not found")) every time it ran — and it runs on everydragoverevent, which fires continuously while dragging. Objects passed toconsole.logare retained by the browser's console heap and can never be garbage-collected, so memory grew unbounded for the duration of each drag (and it spammed the console / added work on a hot path).Fix: removed the hot-path logging. The function now just measures and returns the heights.
2. Reordering doesn't track when nodes are different sizes
The cumulative-height loop in
getHoveringPositiononly assignedlinearIndex/hoveringPositionwhen the pointer landed inside an item's vertical range. When the pointer was below the last item (e.g. dragging into the empty space at the bottom of the tree), the loop never matched, so both values stayed0and the drop indicator snapped to the top of the tree.linearIndexwas also derived directly from the (possibly out-of-range) loop index rather than being clamped against the real linear-item list.Fix: rewrote the calculation to
bottomoffset;linearIndexto the actuallinearItemsrange, matching the original robust behavior.Also removed dead commented-out code left over from the WIP.
Notes
DragBetweenLinealready positions the indicator by summing per-item heights, so it stays consistent with the correctedlinearIndex.itemHeight/itemsHeightArraycontext fields are unchanged.Testing
Type/logic reviewed locally. A full
tsc/jestrun wasn't possible in this environment becausenode_modulesisn't installed (dependency resolution errors are unrelated to these changes).🤖 Generated with Claude Code
Generated by Claude Code