-
-
Notifications
You must be signed in to change notification settings - Fork 202
Refactor Grid Row Selection to use Granular Updates and No-Op Checks #9014
Description
Following the resolution of #9012, we identified that the RowModel visual update failure was caused by a logic bug (isSelected vs isSelectedRow), not an inherent flaw in row.update(). However, to fix the regression quickly, we fell back to using view.update() (full Body diff) for row selection.
This ticket aims to restore O(1) performance for row selection and further optimize VDOM traffic.
Current State & Inefficiencies
- Over-Scoping (O(N) Updates):
selectRowanddeselectRowcurrently triggerme.view.update(). This forces the VDOM engine to diff every mounted row in the grid body, even though only 1 or 2 rows have changed class. For a grid with 50+ mounted rows, this is wasteful. - False Positives (No-Op Updates):
updateRowstoggles theneo-selectedclass and triggers an update blindly. Even if the class was already there (or already missing),row.update()is called, sending a "no change" delta request to the VDOM worker.
The Goal: "Smart" Granular Updates
We want to move back to row.update() and ensure we only send updates when state actually changes.
1. Smart updateRows Logic
Refactor Neo.selection.grid.BaseModel.updateRows to:
- Check the current VDOM state (
row.vdom.cls) before toggling. - Return a boolean or count indicating if any mutation occurred.
- Only call
row.update()if a mutation happened.
2. Restore Granular selectRow / deselectRow
Refactor RowModel logic to leverage the fix from #9012 (correct usage of isSelectedRow) and switch back to granular updates:
- Deselect:
updateRows(oldId)->rowA.update(). - Select:
updateRows(newId)->rowB.update().
3. Disjoint Batching
By issuing two separate row.update() calls synchronously, the App worker's message batching will automatically combine them into a single payload for the VDOM worker, achieving optimal performance without manual batching logic.
Implementation Plan
-
Modify
updateRows(items, silent):- Iterate items.
- For each item, check
row.vdom.cls.includes(selectedCls)vs target state. - If distinct: mutate
cls, setneedsUpdate = true. if (needsUpdate && !silent) row.update().
-
Refactor
selectRow(recordId, silent):- Call
deselectRow(id)(triggers granular update for old row). - Call
updateRows(recordId, silent)(triggers granular update for new row). - Remove
view.update()calls.
- Call
-
Refactor
deselectRow(recordId, silent):- Call
updateRows(recordId, silent). - Remove
view.update()calls.
- Call
This will result in a highly responsive grid selection model that scales with complexity (user interaction speed), not dataset size (mounted rows).