Lattice Grid Buy a licence

demo D53

Sort at a million rows

Timed on the page, and honest about where it runs

measured, main thread

Building…
Loading a live grid…

The configuration

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.css">
<script src="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.js"></script>

<div id="grid" style="height: 540px"></div>

<script>
  const grid = LatticeGrid.createGrid(document.getElementById('grid'), {
    rowKey: 'id',
    selection: 'multiple',
    toolPanel: {
      side: 'left',
      panels: ['columns', 'filters', 'views', 'quick'],
      actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
      exportName: 'lattice-demo',
    },
    columns: [
      { field: 'account', title: 'Account', filter: { type: 'set' } },
      { field: 'service', title: 'Service', filter: { type: 'set' } },
      { field: 'resource', title: 'Resource', layout: { flex: 1, min: 200, max: 320 } },
      { field: 'region', title: 'Region', filter: { type: 'set' } },
      { field: 'environment', title: 'Env', filter: { type: 'set' },
        cell: { decoration: 'pill', variant: { map: {
          prod: 'danger', 'prod-2': 'danger', 'definitely-prod': 'danger',
          staging: 'warning', untagged: 'warning', test: 'info',
          dev: 'success', 'not-prod': 'neutral',
        } } } },
      { field: 'change', title: 'Change', type: 'number',
        layout: { width: 140, min: 140 }, format: { style: 'percent', decimals: 1 } },
      { field: 'cost', title: 'Monthly cost', type: 'number',
        layout: { width: 170, pin: 'end' },
        format: { style: 'currency', currency: 'USD', decimals: 2 }, total: 'sum' },
    ],
    rows,  // one million cloud cost records
  });
</script>

Sorting a million rows without leaving the main thread

Sorting is one of the first places a data grid’s architecture shows through: a naive implementation reorders the DOM row by row, while a column-oriented one reorders an index array and lets virtual scrolling redraw only the rows in view. A developer reaches for this demo when a column click on a large dataset needs to stay responsive rather than freeze the tab, and when the honest answer to “how does this behave at scale” matters more than a synthetic benchmark. Lattice Grid measures the operation in place, reported through the measured, main thread timing shown on the page rather than a claim made in isolation, and the sort runs on the main thread by design: a worker would need to serialise a million rows across the boundary, which costs more than the comparison it is meant to speed up. Clicking a header applies sort.set([{ col, dir }]), the same call used for a hundred rows, and the index rebuild is what changes size, not the code path. Because only the row order changes and not the row objects, memory stays flat rather than doubling with every sort. The result is a number on the page rather than an assurance: how long a click actually takes, on the machine reading it, at a scale most grids never show.

How fast can a JavaScript data grid sort a million rows?

The figure varies by machine and column type, which is why this demo times the sort live on the page rather than quoting a fixed number. Lattice Grid sorts by reordering an index rather than the underlying rows, on the main thread, so the time shown reflects the comparison cost for the visible column at the row count loaded, not a network round trip or a worker handoff.