We use cookies to enhance your experience on the site
CodeWorlds

Performance Optimization

Change Detection OnPush

OnPush is like guards who only check when someone knocks at the gate:

1@Component({
2  selector: 'app-samurai-card',
3  changeDetection: ChangeDetectionStrategy.OnPush,
4  template: \`
5    <div class="card">
6      <h3>{{ samurai().name }}</h3>
7      <p>Clan: {{ samurai().clan }}</p>
8    </div>
9  \`
10})
11export class SamuraiCardComponent {
12  // Component updates ONLY when:
13  // 1. samurai() signal changes reference
14  // 2. An event (click, input) is triggered
15  // 3. Async pipe receives a new value
16  // 4. We manually call cdr.markForCheck()
17
18  samurai = input.required<Samurai>();
19}

Lazy Loading Components with @defer

1<!-- Load when element enters viewport -->
2@defer (on viewport) {
3  <app-heavy-chart [data]="chartData()" />
4} @placeholder {
5  <div class="chart-placeholder">Chart will load when you scroll down...</div>
6} @loading (minimum 500ms) {
7  <app-spinner />
8} @error {
9  <p>Error loading chart</p>
10}
11
12<!-- Load after interaction -->
13@defer (on interaction) {
14  <app-advanced-editor />
15} @placeholder {
16  <button>Click to load editor</button>
17}
18
19<!-- Load after a delay -->
20@defer (on timer(2000)) {
21  <app-recommendations />
22} @placeholder {
23  <p>Loading recommendations...</p>
24}
25
26<!-- Conditional loading -->
27@defer (when isAdmin()) {
28  <app-admin-panel />
29}

Virtual Scrolling

For long lists:

1import { ScrollingModule, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
2
3@Component({
4  imports: [ScrollingModule],
5  template: \`
6    <cdk-virtual-scroll-viewport itemSize="50" class="viewport">
7      <div *cdkVirtualFor="let samurai of samuraiList()" class="item">
8        {{ samurai.name }}
9      </div>
10    </cdk-virtual-scroll-viewport>
11  \`,
12  styles: [\`
13    .viewport {
14      height: 400px;
15    }
16    .item {
17      height: 50px;
18    }
19  \`]
20})
21export class VirtualListComponent {
22  samuraiList = signal<Samurai[]>([]);  // Even 10,000 elements!
23}

NgOptimizedImage

1import { NgOptimizedImage } from '@angular/common';
2
3@Component({
4  imports: [NgOptimizedImage],
5  template: \`
6    <!-- Automatic lazy loading, srcset, preconnect -->
7    <img
8      ngSrc="/images/samurai.jpg"
9      width="800"
10      height="600"
11      priority
12      placeholder="/images/samurai-placeholder.jpg"
13    >
14
15    <!-- Fill mode for responsive images -->
16    <div class="image-container">
17      <img ngSrc="/images/background.jpg" fill>
18    </div>
19  \`,
20  styles: [\`
21    .image-container {
22      position: relative;
23      width: 100%;
24      height: 300px;
25    }
26  \`]
27})
28export class OptimizedImageComponent {}
Go to CodeWorlds