Lattice Grid Buy a licence

demo D95

The memory source

Everything resident, and the columnarisation threshold

source: { mode: 'memory' }

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',
    },
    statusBar: { panels: ['rowCount', 'progress', 'updates', 'selectedCount'] },
    // The default mode, spelled out. columnarBelow is the threshold at which
    // the store stops holding row objects and columnarises: under it the copy
    // is not worth making, over it every sort, filter and total reads a typed
    // array rather than chasing pointers.
    source: { mode: 'memory', columnarBelow: 5000 },
    columns: [
      { field: 'symbol', title: 'Symbol', layout: { width: 130, pin: 'start' } },
      { field: 'name', title: 'Instrument', layout: { flex: 1, min: 170, max: 280 } },
      { field: 'desk', title: 'Desk', filter: { type: 'set' } },
      { field: 'book', title: 'Book', filter: { type: 'set' } },
      { field: 'region', title: 'Region', filter: { type: 'set' } },
      { field: 'price', title: 'Price', type: 'number', layout: { width: 120 },
        format: { decimals: 4 }, filter: { type: 'number' } },
      { field: 'change', title: 'Change', type: 'number', layout: { width: 110 },
        format: { style: 'percent', decimals: 2 } },
      { field: 'volume', title: 'Volume', type: 'number', layout: { width: 120 },
        format: { notation: 'compact' }, filter: { type: 'number' } },
      { field: 'notional', title: 'Notional', type: 'number', layout: { width: 150 },
        format: { style: 'currency', currency: 'USD', notation: 'compact' } },
      { field: 'status', title: 'Status', filter: { type: 'set' }, layout: { width: 110 },
        cell: { decoration: 'pill', variant: { map: { open: 'success', halted: 'danger', settled: 'neutral' } } } },
    ],
    rows,  // 200,000 instrument objects held in memory
  });
</script>

Holding every row in memory, and the columnarisation threshold

The memory source is the default way a JavaScript data grid gets its data: the full row set lives in the browser’s memory as a plain array, with no paging boundary and no round trip for scrolling, sorting or filtering. A developer reaches for it whenever the dataset is small enough to fetch once and keep resident, which in practice covers most admin tools, dashboards and internal reports, even at hundreds of thousands of rows. Lattice Grid selects it with source: { mode: 'memory' }, and above a configurable row count it reorganises the array column by column rather than row by row, because a columnar layout lets a sort or a filter touch one contiguous block of values per column instead of visiting every row’s object and reading one property out of it. That columnarisation threshold is itself a setting, so a grid with wide rows and few of them can defer the conversion, while a grid with a million narrow rows converts early and keeps every sort under a frame budget. Because the whole set is present, group-by, pivot and cross-filtering operate against the true dataset rather than a page of it, and virtual scrolling only ever renders the rows currently in view, so memory footprint scales with columns times visible rows, not columns times total rows.

When should I use the memory source instead of a paged or remote source?

Use the memory source when the full dataset can be fetched in one request and held as a JavaScript array, typically up to the low millions of rows depending on column count. It gives sorting, filtering, grouping and pivoting against the real data with no server round trip. Switch to a paged or remote source once the dataset itself, not just its rendering, is too large to hold resident.