Building a High‑Performance Multi‑Dimensional Table with Konva.js

This article explains how to create a high‑performance, multi‑dimensional table system using Konva.js, covering project overview, feature list, core architecture, module design, key mechanisms such as group rendering, virtual scrolling and batch drawing, implementation details, performance optimizations, and future extensions.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Building a High‑Performance Multi‑Dimensional Table with Konva.js

Konva.js Multi‑Dimensional Table System

Based on Konva.js , this article presents a high‑performance multi‑dimensional table system that supports massive rendering, group management, filtering, sorting, and more, aiming to provide an interactive experience similar to Tencent Docs or Feishu Sheets.

Table of Contents

1. Project Overview

2. Feature List

3. Core Architecture Design

4. Module Description

5. Key Mechanisms

6. Implementation Process

7. Performance Optimization

8. Extensibility

9. Conclusion

1. Project Overview

The project implements a high‑performance two‑dimensional/multi‑dimensional table system with Konva.js, supporting:

Massive table rendering (rows and columns up to millions)

Grouped data display

Multi‑dimensional filtering and sorting

Various cell types (text, image, status tags, custom renderers)

Responsive layout and virtual scrolling optimization

The system is suitable for complex scenarios such as task management, resource scheduling, and project planning.

2. Feature List

Feature Module

Description

Table Rendering

Uses Konva Layer + Group for efficient drawing of cells, borders, and backgrounds.

Group Management

Supports collapsible/expandable groups.

Filtering

Multi‑column field filtering (text, numeric, status).

Sorting

Single‑column and multi‑column sorting logic.

Cell Types

Text, image, status tag, custom renderer.

Interaction

Selection, box selection, multi‑select, hover tips, scroll sync.

Virtual Scrolling

Renders only elements within the viewport to improve performance.

Dynamic Layout

Adaptive row height, column width, and container size.

Batch Update Mechanism

Uses requestAnimationFrame for batch drawing, avoiding redundant renders.

3. Core Architecture Design

Architecture Diagram 1
Architecture Diagram 1
Architecture Diagram 2
Architecture Diagram 2
## 🎯 Main Controller
- table
  - Layer system
    - `backgroundLayer` – background layer
    - `bodyLayer` – main content layer
    - `featureLayer` – feature layer
  - Group system
    - `topLeft Group` – top‑left frozen area
    - `topRight Group` – top‑right frozen area
    - `bottomLeft Group` – bottom‑left frozen area
    - `bottomRight Group` – bottom‑right frozen area
  - Data management
    - **LinearRowsManager**
      - `linearRows: ILinearRow[]` – linear row data
      - `buildLinearRows()` – construct row data
      - `toggleGroup()` – toggle group state
  - Layout system
    - **CellLayout** (abstract base)
      - `GroupTabLayout` – group row layout
      - `RecordRowLayout` – data row layout
      - `AddRowLayout` – add‑row layout
      - `BlankRowLayout` – blank row layout
      - `headerLayout` – header layout
  - Utility classes
    - **VirtualTableHelpers**
      - `getItemMetadata()` – get item metadata
      - `findNearestItem()` – find nearest item
  - Event handling
    - `setupEvents()` – initialize events
    - `scroll()` – scroll handling
    - `handleCellClick()` – cell click handling

4. Module Description

1. Renderer Module

Responsible for visual rendering logic:

Uses Konva.Layer to manage background, content, and interaction layers.

Each row or group of cells is represented by a Konva.Group.

Supports incremental rendering and batch updates.

Fast matrix‑coordinate positioning for rendering regions.

2. Model Module

Provides an abstract data source.

Supports filtering, sorting, group aggregation, and dynamic updates.

Synchronizes data changes with the rendering layer via the observer pattern.

3. Controller Module

Listens to user input events (mouse, scroll, drag).

Controls rendering queue and update cadence.

Manages current selection and focused cell.

Synchronizes with the Model layer for data updates.

5. Key Mechanisms

1. Group Rendering

Each group uses an independent Konva.Group.

When collapsed, only the group header is rendered.

Expanding loads child nodes in batches.

Lazy loading optimizes performance.

2. Virtual Scrolling

Calculates rows and columns that should be rendered within the visible area.

Reduces memory usage and repaint frequency.

Supports synchronized horizontal and vertical scrolling.

3. Batch Draw

private _waitingForDraw = false;
private animQueue: Function[] = [];
public batchDraw() {
  if (!this._waitingForDraw) {
    this._waitingForDraw = true;
    requestAnimationFrame(() => {
      this.animQueue.forEach(fn => fn());
      this.animQueue = [];
      this._waitingForDraw = false;
    });
  }
  return this;
}
private requestAnimFrame(callback: Function) {
  this.animQueue.push(callback);
  if (this.animQueue.length === 1) {
    req(() => {
      const queue = this.animQueue;
      this.animQueue = [];
      queue.forEach(cb => cb());
    });
  }
}
render() {
  this.renderContent();
  this.core.updateScrollBars();
}

6. Implementation Process

1. Simple Konva.js Table Rendering (inefficient for large data)

for (let row = 0; row < 10; row++) {
  for (let col = 0; col < 10; col++) {
    const rect = new Konva.Rect({
      x: col * cellSize,
      y: row * cellSize,
      width: cellSize,
      height: cellSize,
      fill: 'lightgrey',
      stroke: 'black',
      strokeWidth: 1
    });
    layer.add(rect);
  }
}

2. Helper Class – VirtualTableHelpers

Helper Class Diagram
Helper Class Diagram
getVisibleRowRange(frozenRowsHeight: number) {
  const rowCount = this.linearRowsManager.getRowCount();
  const viewportHeight = this.visibleHeight - frozenRowsHeight - this.scrollBarSize;
  const startRow = VirtualTableHelpers.getRowStartIndexForOffset({
    itemType: "row",
    rowHeight: this.getRowHeight,
    columnWidth: this.getColumnWidth,
    rowCount,
    columnCount: this.cols,
    instanceProps: this.instanceProps,
    offset: this.scrollY
  });
  const endRow = VirtualTableHelpers.getRowStopIndexForStartIndex({
    startIndex: Math.max(this.frozenRows, startRow),
    rowCount,
    rowHeight: this.getRowHeight,
    columnWidth: this.getColumnWidth,
    scrollTop: this.scrollY,
    containerHeight: viewportHeight,
    instanceProps: this.instanceProps
  });
  const buffer = 2;
  return {
    start: Math.max(this.frozenRows, startRow - buffer),
    end: Math.min(rowCount - 1, endRow + buffer)
  };
}

7. Performance Optimization

Cell values that involve heavy calculations (e.g., formulas) are processed in a Web Worker.

Data statistics, filtering, sorting, and searching use asynchronous chunking.

Icons and images are cached and reused.

if (textContext && textContext.includes('cacl')) {
  this.alloyWorker.cookie.exportStaion(Math.random() * 10 >= 5 ? 40 : 39).then(result => {
    const groups = this.groups.bottomRight.find(`#${row}-${col}`) as Group[];
    if (groups.length) {
      const textNode = groups[0].children[1] as Konva.Text;
      textNode.text(result);
    }
  });
  textContext = 'Calculating...';
}

8. Extensibility

Future work includes adding features such as highlighting, selection zones, custom column types, and more advanced data analysis.

Future Extension Sketch
Future Extension Sketch

Conclusion

If you have questions, feel free to comment. Many features still need development and polishing; updates will be posted as progress is made. This article aims to spark ideas and guide step‑by‑step implementation of complex table functionalities.

virtual scrollingFrontend ArchitectureKonva.jsmulti-dimensional table
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.