Skip to content

Migrate Data Grid from RevoGrid to Svelte-TableCN (TanStack) #8

@devnull03

Description

@devnull03

1. Problem Statement & Motivation

Current Status: The application currently uses RevoGrid for the main data view.
Pain Point: We are hitting a hard architectural wall regarding custom cell rendering. RevoGrid's reliance on StencilJS and an internal Virtual DOM makes it difficult to render complex Svelte components (e.g., interactive rating widgets, progress bars) inside cells without "alien" syntax, manual lifecycle management, and event bridging issues.
Goal: We need full control over cell rendering to treat cells as native Svelte 5 components while maintaining the high-performance scrolling (60 FPS at 100k+ rows) currently provided by RevoGrid.

2. Proposed Solution

Migrate to [itisyb/svelte-tablecn](https://github.com/itisyb/svelte-tablecn).

  • Core Logic: TanStack Table v8 (Headless, logic-only).
  • Rendering: Svelte 5 (Runes) + Shadcn-Svelte components.
  • Virtualization: tanstack-virtual (Critical for performance).

This "Inversion of Control" architecture allows us to define cell renderers as standard Svelte snippets/components, utilizing fine-grained reactivity ($state, $derived) to update specific text nodes without re-rendering entire rows.

3. Critical Performance Requirements (Risk Mitigation)

Constraint: "Performance above everything else."
Unlike RevoGrid, TanStack Table does not optimize DOM interaction out-of-the-box. We assume full responsibility for the rendering layer. To prevent performance regression, the following Technical Constraints must be enforced during implementation:

  1. Mandatory Virtualization:
    • The grid must never render the full dataset. tanstack-virtual must be implemented immediately.
    • Overscan: Configure overscan (buffer) to 5-10 rows to handle rapid scrolling without whitespace flashing.
  2. Fixed Row Heights (Layout Thrashing Prevention):
    • Avoid dynamic height measurement if possible. Hardcode row height (e.g., 48px) in the virtualizer options. This changes scroll math from O(N) measurement to O(1) calculation, which is essential for massive datasets.
  3. Keying Strategy:
    • Use stable unique IDs (e.g., row.original.id) for Svelte {#each} keys to minimize DOM node destruction/re-creation during virtualization.
  4. Column Virtualization:
    • If the visible column count exceeds 30, implement horizontal virtualization (column windowing) to limit the total DOM nodes in the viewport.

4. Migration Roadmap

Phase 1: Foundation & Data Definitions

  • Install dependencies: @tanstack/svelte-table, @tanstack/svelte-virtual, svelte-tablecn (components).
  • Define ColumnDef array.
  • Port data fetching logic to populate a $state or Svelte Store compatible with TanStack data prop.

Phase 2: The Virtualization Layer (Blocker)

  • Implement the table container with tanstack-virtual logic before adding complex cell renderers.
  • Benchmark: Load 10,000 dummy rows. Verify scroll FPS is consistent with RevoGrid baseline. If lag occurs here, stop and optimize element keying or row estimation logic.

Phase 3: Custom Cell Renderers

  • Replace string/HTML injection with Svelte Snippets.
    {#snippet cellStatus(value)}
      <Badge variant={value === 'Active'? 'default' : 'destructive'}>
        {value}
      </Badge>
    {/snippet}
  • Integrate interactive components (e.g., Rating Widget) directly into the cell snippets using Svelte Context for state sharing.

Phase 4: Feature Parity Restoration

  • Sorting: Implement getSortedRowModel.
  • Filtering: Re-implement column filters using Shadcn inputs.
  • Selection: Wire up row selection state (rowSelection).

5. Success Metrics

  • Rendering: Zero usage of componentDidRender or manual DOM manipulation hacks.
  • Performance: < 300MB Memory usage on 100k rows.
  • UX: No visible stutter (jank) during fast scrolling on average hardware.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions