-
Notifications
You must be signed in to change notification settings - Fork 2.7k
perf(compact): implement faster vertical compaction #2152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Hi, This is very interesting! Thanks for implementing. This changes the behavior of the default compactor, does it not? Or are the results the same and this is purely performance? |
|
Additionally, can you see this being implemented horizontally too, and if so, can we remove a bunch of old code? I would be very happy with that. |
|
Hi!
I think it does, but hopefully only in subtle ways (weird edge cases). I'll try to quantify this with some tests, let me get back to you.
I haven't tried, but I suspect horizontal compaction needs a different approach. While grids can grow vertically indefinitely, the number of columns is constant, so it looks like a (slightly?) separate problem. I'm thinking t might be safer to take it on separately 🤔 would you see this as a show stopper for this PR? |
|
I don't want to leave the code base with a lot of dead code, so it's fairly high priority. I think this is a measurable improvement and the change is actually easier to read, so I'm excited about what it might bring. |
|
I've added two minimal tests illustrating differences in behavior. The first one produces a more compact layout, the second one produces a less compact result (which may be considered a regression) than current Running some randomized tests (roughly same inputs from the new fuzzy tests), I've found the new compaction algorithm to produce equivalent layouts for about 65-75% of inputs. This may be indeed too much of a deviation. However, I think it comes down more to the user experience while moving items: Does the layout change in unexpected/unintended ways while dragging and dropping? Regarding that, I'm fairly confident it works well (if not better): Screen.Recording.2025-06-27.at.13.49.07.movIn the end, it's your call of course :) let me know if you think the changed behavior is good enough. I might take a stab at horizontal compaction in that case |
|
Playing with it more, I found the algorithm to be surprisingly powerful as it can support manipulation (move/resize) as well by applying the manipulation, sorting cleverly, and using compaction as a repair step. I was able to implement a RGL alternative that's more opinionated (less options, e.g. no horizontal compaction) but much, much faster, based on it: https://github.com/morris/fast-grid-layout - may be interesting for you as well :) |
|
That's pretty cool @morris. I'll spend some time with this again. I'm a performance junkie and you really whipped my butt with this one. |
This RFC proposes a comprehensive rewrite of react-grid-layout in TypeScript with a modernized, composable API while maintaining backwards compatibility. Key changes: - Pure TypeScript core with no React dependencies in layout algorithms - Composable interfaces: Compactor, PositionStrategy, DragConfig, ResizeConfig, DropConfig - Hooks-based API (useGridLayout, useResponsiveLayout, useContainerWidth) - Fast compaction algorithm (O(n log n) vs O(n²)) - PR #2152 - Drag threshold fix (onDragStart only fires after 3px movement) - PR #1411 - Wrap compact mode support via Compactor interface - PR #1773 - Legacy wrapper for 100% backwards compatibility - data-grid prop isolated to legacy wrapper only Breaking changes in v2: 1. onDragStart requires mouse movement (3px threshold) 2. Immutable callback parameters 3. data-grid prop only in legacy wrapper 4. Fast compaction algorithm by default (use legacy* for exact v1 behavior) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Auto code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. Note: This PR was created before the v2 TypeScript rewrite and targets the legacy 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
|
Ok this is pretty good. |
Implements a "rising tide" compaction algorithm that achieves significant
performance improvements for large layouts:
- 50 items: ~6x faster
- 100 items: ~6x faster
- 200 items: ~16x faster
- 500 items: ~45x faster
The algorithm works by:
1. Sorting items by (y, x, static) - top-to-bottom, left-to-right
2. Maintaining a "tide" array tracking the highest occupied row per column
3. Moving each item up to meet the tide (closing gaps)
4. Checking for collisions with static items and adjusting as needed
This avoids the recursive collision resolution of the standard compactor,
reducing complexity from O(n²) to O(n log n).
Usage:
```tsx
import { fastVerticalCompactor } from 'react-grid-layout/extras';
<GridLayout compactor={fastVerticalCompactor} ... />
```
Based on the algorithm from PR #2152 by @morris, migrated to the v2
TypeScript architecture.
Closes #2152
…react-grid-layout#2184) Implements a "rising tide" compaction algorithm that achieves significant performance improvements for large layouts: - 50 items: ~6x faster - 100 items: ~6x faster - 200 items: ~16x faster - 500 items: ~45x faster The algorithm works by: 1. Sorting items by (y, x, static) - top-to-bottom, left-to-right 2. Maintaining a "tide" array tracking the highest occupied row per column 3. Moving each item up to meet the tide (closing gaps) 4. Checking for collisions with static items and adjusting as needed This avoids the recursive collision resolution of the standard compactor, reducing complexity from O(n²) to O(n log n). Usage: ```tsx import { fastVerticalCompactor } from 'react-grid-layout/extras'; <GridLayout compactor={fastVerticalCompactor} ... /> ``` Based on the algorithm from PR react-grid-layout#2152 by @morris, migrated to the v2 TypeScript architecture. Closes react-grid-layout#2152
Description
This PR implements fast vertical compaction using a "rising tide" algorithm. For all practical cases, the algorithm has linear time complexity, and requires almost zero additional memory allocations (after cloning and sorting the layout).
While working with larger layouts (200+ items), dragging and dropping items felt sluggish, and I found
compact()to be one of the major bottlenecks with lots of recursion and allocations/garbage collection. The following two screenshots from the Chrome profiler should give an idea of the improvement.Current
master:New algorithm:
Note that the comparison is not fully representative. The recordings were done on random, distinct 300-item layouts (one shot).
Let me know if there's interest, happy to add explanations and/or tests :)
What type of PR is this? (check all applicable)
Related Tickets & Documents
Mobile & Desktop Screenshots/Recordings
Added tests?
Added to documentation?