Virtual Columns

Column virtualization enables you to render only the columns that are in the current viewport. This improves the performance because fewer elements are rendered by the Grid and the browser.

When to use

Use with Grids that have large number of columns in order to reduce the number of rendered elements. Consider leaving it disabled for grids that have only a few non-visible columns. The column virtualization requires the grid to do extra work and might reduce performance in some cases. As always, it's best to perform your own measurements when fine-tuning the application performance.

Prerequisites

To allow the component to virtualize the columns and for the feature to work properly, make sure that:

  • Scrolling is enabled.
  • The width of all columns is set.

Setup

To enable column virtualization, set the virtualColumns property to true.

import {
    Component,
    ViewEncapsulation
} from '@angular/core';

import { OrdersService } from './orders.service';

@Component({
    providers: [OrdersService],
    encapsulation: ViewEncapsulation.None,
    styles: [`
        .k-grid tbody td {
            white-space: nowrap;
            line-height: 20px;
            padding: 8px 12px;
        }
    `],
    selector: 'my-app',
    template: `
        <kendo-grid
          [loading]="loading"
          [kendoGridBinding]="data"
          [pageSize]="30"
          scrollable="virtual"
          [rowHeight]="36"
          [height]="450"
          [virtualColumns]="true"
          style="width: 750px;"
        >
        <kendo-grid-column field="OrderID" [width]="80" title="ID"></kendo-grid-column>

        <kendo-grid-column field="EmployeeID" [width]="80" title="Employee ID"></kendo-grid-column>
        <kendo-grid-column field="Freight" [width]="100" title="Freight"></kendo-grid-column>
        <kendo-grid-column field="OrderDate" [width]="200" title="Order Date" format="d"></kendo-grid-column>
        <kendo-grid-column field="RequiredDate" [width]="200" title="Required Date" format="d"></kendo-grid-column>

        <kendo-grid-column-group title="Shipment">
            <kendo-grid-column field="ShipName" title="Name" [width]="200"></kendo-grid-column>
            <kendo-grid-column field="ShipAddress" title="Address" [width]="200"></kendo-grid-column>
            <kendo-grid-column field="ShipCity" title="City" [width]="100"></kendo-grid-column>
            <kendo-grid-column field="ShipCountry" title="Country" [width]="100"></kendo-grid-column>
            <kendo-grid-column field="ShipPostalCode" title="Postal Code" [width]="100"></kendo-grid-column>
            <kendo-grid-column field="ShippedDate" [width]="200" title="Date" format="d"></kendo-grid-column>
        </kendo-grid-column-group>
        <kendo-grid-column-group title="Customer">
            <kendo-grid-column field="Customer.CustomerID" [width]="80" title="ID"></kendo-grid-column>
            <kendo-grid-column field="Customer.CompanyName" title="Company Name" [width]="200"></kendo-grid-column>
            <kendo-grid-column field="Customer.ContactName" title="Contact Name" [width]="200"></kendo-grid-column>
            <kendo-grid-column field="Customer.ContactTitle" title="Contact Title" [width]="200"></kendo-grid-column>
            <kendo-grid-column field="Customer.Address" title="Address" [width]="200"></kendo-grid-column>
            <kendo-grid-column field="Customer.City" title="Postal Code" [width]="100"></kendo-grid-column>
            <kendo-grid-column field="Customer.PostalCode" title="Postal Code" [width]="100"></kendo-grid-column>
            <kendo-grid-column field="Customer.Country" title="Country" [width]="100"></kendo-grid-column>
            <kendo-grid-column field="Customer.Phone" title="Phone" [width]="200"></kendo-grid-column>
            <kendo-grid-column field="Customer.Fax" title="Fax" [width]="200"></kendo-grid-column>
        </kendo-grid-column-group>

        <kendo-grid-column-group title="Shipper">
            <kendo-grid-column field="Shipper.CompanyName" title="Company Name" [width]="200"></kendo-grid-column>
            <kendo-grid-column field="Shipper.Phone" title="Phone" [width]="200"></kendo-grid-column>
        </kendo-grid-column-group>
      </kendo-grid>
    `
})
export class AppComponent {
    public loading = true;
    public data: any[] = [];

    constructor(service: OrdersService) {
        service.fetch().subscribe((result: any) => {
            this.data = result.data;
            this.loading = false;
        });
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { GridModule } from '@progress/kendo-angular-grid';

import { AppComponent } from './app.component';

@NgModule({
  imports: [ BrowserModule, BrowserAnimationsModule, GridModule, HttpClientModule ],
  declarations: [ AppComponent ],
  bootstrap: [ AppComponent ]
})

export class AppModule { }
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class OrdersService  {
    private BASE_URL = 'https://odatasampleservices.azurewebsites.net/V4/Northwind/Northwind.svc/';

    constructor(private http: HttpClient) {
    }

    public fetch(): Observable<GridDataResult> {
        return this.http
            .get(`${this.BASE_URL}Orders?$expand=Customer,Shipper`)
            .pipe(
                map(response => (<GridDataResult>{
                    data: response.value.map(item => Object.assign(item, {
                        OrderDate: new Date(item.OrderDate),
                        RequiredDate:  new Date(item.RequiredDate),
                        ShippedDate:  new Date(item.ShippedDate)
                    })),
                    total: response.value.length
                }))
            );
    }
}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

In this article