Virtual scrolling helps show only the visible items in a long list. This makes the app faster and smoother.
Virtual scrolling for large lists in Angular
import { Component } from '@angular/core'; import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; @Component({ selector: 'app-virtual-scroll', template: ` <cdk-virtual-scroll-viewport itemSize="50" class="viewport"> <div *cdkVirtualFor="let item of items" class="item"> {{item}} </div> </cdk-virtual-scroll-viewport> `, styles: [ `.viewport { height: 200px; width: 300px; border: 1px solid #ccc; } .item { height: 50px; display: flex; align-items: center; padding-left: 10px; border-bottom: 1px solid #eee; }` ] }) export class VirtualScrollComponent { items = Array.from({ length: 1000 }).map((_, i) => `Item #${i + 1}`); }
The cdk-virtual-scroll-viewport sets the visible area and item size.
The *cdkVirtualFor directive works like *ngFor but only renders visible items.
<cdk-virtual-scroll-viewport itemSize="40" class="viewport"> <div *cdkVirtualFor="let item of items" class="item"> {{item}} </div> </cdk-virtual-scroll-viewport>
<cdk-virtual-scroll-viewport itemSize="60" class="viewport"> <div *cdkVirtualFor="let item of items" class="item"> {{item}} </div> </cdk-virtual-scroll-viewport>
<cdk-virtual-scroll-viewport itemSize="50" class="viewport"> <div *cdkVirtualFor="let item of []" class="item"> No items to show </div> </cdk-virtual-scroll-viewport>
<cdk-virtual-scroll-viewport itemSize="50" class="viewport"> <div *cdkVirtualFor="let item of ['Only one item']" class="item"> {{item}} </div> </cdk-virtual-scroll-viewport>
This Angular app shows a list of 1000 items using virtual scrolling. Only visible items render, making scrolling smooth and fast. The viewport has a fixed height and width with keyboard focus styles for accessibility.
import { Component } from '@angular/core'; import { ScrollingModule } from '@angular/cdk/scrolling'; import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @Component({ selector: 'app-root', template: ` <h2>Virtual Scroll Example</h2> <cdk-virtual-scroll-viewport itemSize="50" class="viewport" aria-label="List of items"> <div *cdkVirtualFor="let item of items" class="item" tabindex="0"> {{item}} </div> </cdk-virtual-scroll-viewport> `, styles: [ `.viewport { height: 200px; width: 300px; border: 1px solid #ccc; overflow: auto; } .item { height: 50px; display: flex; align-items: center; padding-left: 10px; border-bottom: 1px solid #eee; } .item:focus { outline: 2px solid #1976d2; background-color: #e3f2fd; }` ] }) export class AppComponent { items = Array.from({ length: 1000 }).map((_, i) => `Item #${i + 1}`); } @NgModule({ declarations: [AppComponent], imports: [BrowserModule, ScrollingModule], bootstrap: [AppComponent] }) export class AppModule {}
Virtual scrolling improves performance by rendering only visible items, reducing DOM size.
Time complexity for rendering is O(visible items), not total items.
Common mistake: forgetting to set itemSize causes wrong scroll behavior.
Use virtual scrolling when lists are very long; for short lists, normal *ngFor is simpler.
Virtual scrolling shows only visible list items to improve speed.
Use cdk-virtual-scroll-viewport and *cdkVirtualFor in Angular.
Set fixed itemSize and style viewport for best results.