Skip to content

Refactor Grid Row Selection to use Granular Updates and No-Op Checks #9014

@tobiu

Description

@tobiu

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

  1. Over-Scoping (O(N) Updates): selectRow and deselectRow currently trigger me.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.
  2. False Positives (No-Op Updates): updateRows toggles the neo-selected class 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

  1. Modify updateRows(items, silent):

    • Iterate items.
    • For each item, check row.vdom.cls.includes(selectedCls) vs target state.
    • If distinct: mutate cls, set needsUpdate = true.
    • if (needsUpdate && !silent) row.update().
  2. 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.
  3. Refactor deselectRow(recordId, silent):

    • Call updateRows(recordId, silent).
    • Remove view.update() calls.

This will result in a highly responsive grid selection model that scales with complexity (user interaction speed), not dataset size (mounted rows).

Metadata

Metadata

Assignees

Labels

aicoreCore framework functionalityenhancementNew feature or requestperformancePerformance improvements and optimizations

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions