Remote Operations
We recommend server-side data processing for large datasets. The ODataStore supports server-side paging, filtering, and sorting. DevExtreme provides extensions that help implement data processing for ASP.NET and PHP servers. You can also use the third-party extension for MongoDB. If these extensions do not suit your data source, implement server-side data processing manually according to the protocol described in the Custom Sources article.
Specify the remoteOperations option to notify the DataGrid of the server's data processing operations.
jQuery
$(function() { $("#dataGridContainer").dxDataGrid({ // ... remoteOperations: { filtering: true, paging: true, sorting: true, groupPaging: true, grouping: true, summary: true } }); });
Angular
<dx-data-grid ... > <dxo-remote-operations [filtering]="true" [paging]="true" [sorting]="true" [summary]="true" [grouping]="true" [groupPaging]="true"> </dxo-remote-operations> </dx-data-grid>
import { DxDataGridModule } from "devextreme-angular"; // ... export class AppComponent { // ... } @NgModule({ imports: [ // ... DxDataGridModule ], // ... })
Deferred Selection
Use deferred mode to increase the DataGrid's performance when selecting multiple rows at once. In this mode, only the API (for example, the getSelectedRowsData() or getSelectedRowKeys() method) can request the DataGrid data. Assign true to the selection.deferred option to use deferred selection.
jQuery
$(function(){ $("#dataGridContainer").dxDataGrid({ // ... dataSource: { store: { type: "odata", url: "https://js.devexpress.com/Demos/DevAV/odata/Products", key: "Product_ID" } }, selection: { mode: "multiple", allowSelectAll: true, deferred: true } }); });
Angular
<dx-data-grid [dataSource]="dataSource"> <dxo-selection mode="multiple" [allowSelectAll]="true" [deferred]="true"> </dxo-selection> </dx-data-grid>
import { DxDataGridModule } from "devextreme-angular"; import "devextreme/data/odata/store"; // ... export class AppComponent { dataSource = { store: { type: "odata", url: "https://js.devexpress.com/Demos/DevAV/odata/Products", key: "Product_ID" } } } @NgModule({ imports: [ // ... DxDataGridModule ], // ... })
The following tasks require using different API in deferred mode:
Setting initial selection
You should use the selectionFilter instead of the selectedRowKeys option to set the initially selected rows in deferred mode. Pass a filter expression to define records that should be selected.
jQuery
JavaScript$(function () { $("#dataGridContainer").dxDataGrid({ // ... selectionFilter: ["Task_Status", "=", "Completed"] }); });
Angular
HTMLTypeScript<dx-data-grid ... [selectionFilter]="['Task_Status', '=', 'Completed']"> </dx-data-grid>
import { DxDataGridModule } from "devextreme-angular"; // ... export class AppComponent { // ... } @NgModule({ imports: [ // ... DxDataGridModule ], // ... })
The DataGrid changes the selectionFilter option's value internally when a user selects a row. You can use the following code to obtain this option's value and send it to the server:
jQuery
JavaScriptfunction sendSelectedRows() { var selectionFilter = dataGridInstance.option("selectionFilter"); $.ajax({ method: "POST", url: "url/to/data/processing/method", data: { filter: (selectionFilter ? JSON.stringify(selectionFilter) : null) } }); }
Angular
TypeScriptimport { ..., ViewChild } from "@angular/core"; import { HttpClient, HttpClientModule } from "@angular/common/http"; import { DxDataGridModule, DxDataGridComponent } from "devextreme-angular"; // ... export class AppComponent { @ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent; // Prior to Angular 8 // @ViewChild(DxDataGridComponent) dataGrid: DxDataGridComponent; constructor(private httpClient: HttpClient) { } sendSelectedRows() { var selectionFilter = this.dataGrid.instance.option("selectionFilter"); this.httpClient .post("url/to/data/processing/method", "filter: " + (selectionFilter ? JSON.stringify(selectionFilter) : null) ) .subscribe(); } } @NgModule({ imports: [ // ... DxDataGridModule, HttpClientModule ], // ... })
Checking whether a row is selected
Use the isRowSelected(data) method to determine whether a row is selected.
Getting the selected rows' data
In deferred mode, the getSelectedRowsData() and getSelectedRowKeys() methods return a native Promise or a jQuery.Promise when you use jQuery. Get the data within the callback function that resolves the Promise. This is data before being processed in the DataSource.
See Also
- key in ArrayStore | CustomStore | LocalStore | ODataStore
Lookup Optimization
As a rule, a lookup column contains IDs from a main data source field but displays human-readable values from its own data source. When the DataGrid first launches, it loads data from both data sources which causes performance to decrease.
You can send the human-readable values from the server as a part of the main data source alongside the IDs (like in this example) to optimize the lookup column. In this case, use the column's calculateDisplayValue option to specify which field provides the human-readable values. With this optimization, the lookup data source is not loaded until a user starts editing the lookup column.
jQuery
$(function () { $("#dataGridContainer").dxDataGrid({ //... columns: [{ caption: "Customer", // "CustomerName" provides human-readable values calculateDisplayValue: "CustomerName", dataField: "CustomerID", lookup: { valueExpr: "CustomerID", displayExpr: "ContactName", dataSource: { store: { // ... key: "CustomerID" } } } }, // ... ] }); });
Angular
<dx-data-grid ...> <dxi-column caption="Customer" dataField="CustomerID" calculateDisplayValue="CustomerName"> <!-- "CustomerName" provides human-readable values --> <dxo-lookup [dataSource]="dataSource" displayExpr="ContactName" valueExpr="CustomerID"> </dxo-lookup> </dxi-column> </dx-data-grid>
import { DxDataGridModule } from "devextreme-angular"; import "devextreme/data/array_store"; // or // import "devextreme/data/odata/store"; // import "devextreme/data/custom_store"; export class AppComponent { dataSource: any; constructor() { this.dataSource = { store: { // ... key: "CustomerID" } } } } @NgModule({ imports: [ // ... DxDataGridModule ], // ... })
See Also
Data Navigation
We recommend configuring one of the following features for a user to navigate a large dataset:
Pager
The pager allows a user to switch between pages in the dataset. This is the default navigation method.Virtual scrolling
Virtual scrolling allows users to scroll page by page or jump to any page in the dataset. To enable it, set scrolling.mode to "virtual".Infinite scrolling
In this mode, users scroll data page by page, but cannot skip pages. Use this mode if the virtual scrolling mode reduces performance, and navigation via the pager does not suit your case. To enable infinite scrolling, set scrolling.mode to "infinite".
Use the paging.pageSize to specify the number of rows that are loaded at a time. The bigger this value, the fewer requests are sent to the database but increases the data transfer rate. This option is applied regardless of the specified navigation method.
Rendering Optimization
The widget renders all rows and columns once the data is loaded. To improve performance, set the rowRenderingMode and columnRenderingMode options in the scrolling object to "virtual". These options specify that UI elements are only rendered when they come into the viewport.
Use virtual row rendering when paging is disabled or the pageSize is more than the default value.
Virtual column rendering can be used when there are more than 20 columns outside the viewport.
Cells with complex content (predefined templates, command columns, editors) can be rendered after cells with simple content. To do that, enable the renderAsync option. In addition, you can enable the same option for individual columns if they use a content-heavy cellTemplate.
If you have technical questions, please create a support ticket in the DevExpress Support Center.
We appreciate your feedback.