Skip to content

[internal] Headless virtualization plugin#21093

Merged
cherniavskii merged 56 commits into
mui:masterfrom
cherniavskii:headless-virtualization
Feb 13, 2026
Merged

[internal] Headless virtualization plugin#21093
cherniavskii merged 56 commits into
mui:masterfrom
cherniavskii:headless-virtualization

Conversation

@cherniavskii

Copy link
Copy Markdown
Member

No description provided.

@cherniavskii cherniavskii added scope: data grid Changes related to the data grid. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. labels Jan 26, 2026
@mui-bot

mui-bot commented Jan 26, 2026

Copy link
Copy Markdown

Deploy preview: https://deploy-preview-21093--material-ui-x.netlify.app/

Bundle size report

Bundle Parsed size Gzip size
@mui/x-data-grid ▼-93B(-0.02%) ▼-10B(-0.01%)
@mui/x-data-grid-pro ▼-99B(-0.02%) ▼-3B(0.00%)
@mui/x-data-grid-premium ▼-99B(-0.01%) ▼-16B(-0.01%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 🔺+598B(+0.51%) 🔺+161B(+0.45%)

Details of bundle changes

Generated by 🚫 dangerJS against 6e277f4

@cherniavskii
cherniavskii force-pushed the headless-virtualization branch from 4212fbf to b5d0522 Compare January 26, 2026 16:03
@cherniavskii
cherniavskii marked this pull request as ready for review January 28, 2026 20:25
Comment thread examples/data-grid-headless/src/App.tsx
@cherniavskii cherniavskii changed the title [data-grid-headless] Add virtualization [internal] Headless virtualization plugin Jan 29, 2026
@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jan 30, 2026

const scrollbarVerticalRef = useEventCallback(this.refSetter('scrollbarVertical'));
const scrollbarHorizontalRef = useEventCallback(this.refSetter('scrollbarHorizontal'));
const scrollbarVerticalRef = useScrollbarRefCallback(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why was this not needed in the material grid?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the MUI X Data Grid it was contained in https://github.com/mui/mui-x/blob/master/packages/x-data-grid/src/components/virtualization/GridVirtualScrollbar.tsx
It didn't matter much, because both virtualization layout and virtual scrollbar are internal details in MUI X Data Grid.
But in the headless data grid, we want as easy setup as possible, hence the change.
It's worth noting that these changes do not impact MUI X Data Grid, since it uses LayoutDataGridLegacy, while in the headless data grid we use LayoutDataGrid.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That means we have duplicated code now, right?
That would be nice to avoid. That being said I'll probably refactor the virtual scrollbars code (for other products using the virtualizer - some might want them) and I'd handle the duplication then, so feel free to leave it in (maybe with a comment?) for now.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I forgot that LayoutDataGridLegacy extends LayoutDataGrid, I'll fix that

Comment thread packages/x-data-grid-headless/src/plugins/sorting/sorting.ts Outdated
Comment thread packages/x-data-grid-headless/src/plugins/internal/rows/rows.ts Outdated

@arminmeh arminmeh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor things to consider, but we can merge the PR and deal with those later as well

/>
)}
{hasScrollY && (
<DataGridVirtualScrollbar position="vertical" hasOppositeScrollbar={hasScrollX} />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not so important, since it is a demo app, but
With macOS's option to automatically show scrollbars based on mouse or trackpad, the scrollbars never show.

}
});

resolvedUserPlugins.forEach((plugin) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any use case in mind, but at some point we might want to allow user plugins to be even before the internal plugins...
This is just a thought, you can leave the code as-is for now.

});
});

describe('rows to render', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a test where virtualization strips some rows is missing

});
});

describe('columns to render', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a test where virtualization strips some columns is missing


// Verify the hook exists and can be used
const dimensions = apiRef.current!.api.virtualization.hooks.useDimensions;
expect(dimensions).to.be.a('function');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we test the number of rows being rendered (number increasing by decreasing the height)?

);

// Verify the API is available
expect(apiRef.current!.api.virtualization.getScrollPosition).to.be.a('function');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we check the actual numbers here?

});
});

describe('hooks', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how much value it makes to test that we are getting a function. Most of these are covered by type checks

Comment on lines +94 to +95
const DEFAULT_ROW_HEIGHT = 52;
const DEFAULT_COLUMN_WIDTH = 100;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these two values be in the constants of the respective plugins?

Comment on lines +126 to +127
const rowBufferPx = params.rowBufferPx ?? 150;
const columnBufferPx = params.columnBufferPx ?? 150;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you extract the default buffer as a constant?

previousRun.processorNames.every((name, index) => name === processorNames[index]);

let startIndex = 0;
let input = this.options.getInitialValue();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To save some computation time, we can set this to null here and call getInitialValue() if it does not get filled by the previous output.

@cherniavskii
cherniavskii merged commit e44ee3c into mui:master Feb 13, 2026
22 checks passed
@cherniavskii
cherniavskii deleted the headless-virtualization branch June 30, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: data grid Changes related to the data grid. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants