Skip to content

RFC: Component-Based Grid Rows (Neo.grid.Row) for Granular Updates #8964

@tobiu

Description

@tobiu

Current Architecture

Currently, Neo.grid.Body acts as a monolithic renderer. It manages a large VDOM structure representing all visible rows.

  • Rendering: createViewData iterates through the store and generates a massive array of VDOM objects for rows and cells.
  • Updates: When a single record changes (onStoreRecordChange), grid.Body often triggers a full update(), sending the entire grid body VDOM to the worker (though diffing minimizes DOM ops, the serialization/transport cost is O(N)).
  • Component Columns: grid.Body manually instantiates, updates, and destroys components (like Sparklines) within cells, managing their lifecycle via custom logic (cellRenderer, cleanupComponentInstances).

The Proposal: Neo.grid.Row

Refactor the Grid to use a "Composed Architecture" where each row is a Neo.component.Base instance.

Core Concepts

  1. Row Component: Create a new class Neo.grid.Row extending Neo.component.Base.
    • Configs: record, columns, rowIndex, gridContainer.
    • Reactivity: afterSetRecord triggers a VDOM update for only that row instance.
  2. Row Pooling: Neo.grid.Body maintains a fixed pool of Neo.grid.Row instances (based on availableRows + buffer).
    • Scrolling: Instead of regenerating VDOM objects, grid.Body updates the configs of existing Row components (row.set({ record: newRecord, rowIndex: newIndex })).
  3. Container Composition: grid.Body manages these rows as standard items.

Benefits

  1. Granular Updates (O(1)): A record update triggers a VDOM update only for the specific Neo.grid.Row instance. The parent grid.Body does not need to re-render or diff the entire table.
  2. Simplified Lifecycle: Component columns (Sparklines, Widgets) become standard children of the Row component. Their lifecycle (mount/unmount) is handled automatically by the framework's standard component tree logic, removing the fragile manual management in grid.Body.
  3. Cleaner Architecture: Separation of concerns. grid.Body manages the viewport and scrolling. grid.Row manages the content and cell rendering.
  4. Stability: Eliminates "Zombie Canvas" and context-loss bugs caused by manual VDOM manipulation, as the framework ensures component state persistence.

Challenges / Considerations

  1. Memory Overhead: Creating ~50 component instances vs raw VDOM objects. (Deemed negligible for modern apps).
  2. Initial Render: Instantiation time for the row pool.
  3. Refactoring: Significant changes to Neo.grid.Body, Neo.grid.column.Base (renderers might need adjustment), and CSS targeting (ensuring Neo.grid.Row renders the correct class/structure).

Implementation Strategy

  1. Prototype Neo.grid.Row: Create the class and ensure it can render a record given a set of columns.
  2. Refactor Neo.grid.Body:
    • Remove createRow VDOM generation.
    • Implement createRowPool to instantiate components.
    • Update onStoreRecordChange to find the matching Row component and call set().
    • Update scrolling logic to recycle Row components instead of VDOM nodes.

Future Potential

  • Drag & Drop: Row reordering becomes standard component drag-and-drop.
  • Row Expansion: Implementing "Row Expander" (nested grids/details) becomes trivial (just adding items to the Row component).

Metadata

Metadata

Assignees

Labels

aiarchitectureArchitecture related issuesenhancementNew feature or requestepicA big time intense ticket with related sub-tasks

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions