developer guide
Memory source
Hand the grid an array and it does the rest: sort, filter, group, total and pivot a million rows in the browser, with nothing to configure.
The default, and the fast one
The memory source holds every row and runs the whole pipeline in the browser: filter, then sort, then group, then total, then pivot. It is the default, so a grid handed an array of rows is already using it, and there is nothing to wire up. A million rows across thirty columns is the design target, which means that for most applications this is not a starting point you grow out of, it is the answer.
createGrid(el, {
columns,
rowKey: 'id',
rows, // the whole array; that is the whole configuration
// source: { mode: 'memory' } is the default and can be left out
});
Because the rows are all present, every operation is instant and exact. Sorting does not re-query anything, a filter shows a true count rather than the count of a fetched window, and a total is the total of the data rather than of a page. This is the benefit that a server source trades away, so it is worth keeping as long as the data fits.
One pipeline, memoised
The pipeline is a chain of index arrays. Filtering produces the surviving rows, sorting permutes those, grouping buckets them into a tree, and flattening produces what the grid draws. Every stage is memoised against its inputs, so changing the sort re-runs the sort and leaves the filter result untouched, and no stage clears another. Nothing outside the visible window is ever materialised into a row object, which is what lets a million rows stay responsive rather than allocating a million objects up front.
Load data after the grid
Data usually arrives after the grid does. Build it empty, and the sort, filters, grouping and column
layout you set up in the meantime all survive and apply to the new rows when they land.
rows.load replaces everything; rows.apply and rows.queue take a
delta when you have one.
const grid = createGrid(el, { columns, rowKey: 'id', rows: [] });
grid.overlay.show('loading');
const data = await fetch('/api/circuits').then((r) => r.json());
grid.rows.load(data); // the sort, filters and grouping you set up survive
grid.overlay.hide();
Trimming the memory footprint
By default the store keeps the row objects you hand it by reference, so rows.data() returns
those exact objects. If you can let go of the source array and do not depend on caller identity, set
ingest.retainSource to false and the store keeps only the packed columns,
reconstructing a plain row object on demand. Cell values are identical either way; what changes is that
rows.data() then returns a fresh object each call rather than the object you passed in.
createGrid(el, {
columns,
rowKey: 'id',
rows,
ingest: { retainSource: false }, // keep only the packed columns
});
The saving is the store's own copy of the references, not the objects themselves, so the footprint drops materially only when the grid becomes the sole holder of the data.
When to move on
Reach past the memory source only when the data genuinely does not fit or does not exist yet in the browser: beyond roughly a million rows, or when it lives behind an API. At that point a paged or remote source moves the work to the server, or a streaming source loads it progressively and then promotes back to a memory source once it is all here. Do not make that trade before you have measured that memory is too slow, because it usually is not.
See it running: the memory source, and a million rows sorted and filtered in the tab. For the full list of options, start from connect your data.