Week 09 · Day 02 — OnPush 與 trackBy

學習目標

  • ChangeDetectionStrategy.OnPush 優化
  • markForCheck() 手動標記檢查
  • trackBy 提升列表更新效能

重點

OnPush 策略

import { ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'app-optimized',
  changeDetection: ChangeDetectionStrategy.OnPush,  // 只在需要時檢查
  template: `{{ count }}`
})
export class OptimizedComponent {
  count = 0;

  constructor(private cdr: ChangeDetectorRef) {}

  increment(): void {
    this.count++;
    this.cdr.markForCheck();   // 通知 Angular:我要更新了
  }
}
- OnPush 下只有以下情況才檢查: - @Input 收到「新參考值」 - 元件內事件被觸發 - markForCheck() 被呼叫 - async pipe 有值送來 - markForCheck():手動標記「需要重新檢查」

trackBy:列表更新 - 告訴 Angular「用 id 辨識每個項目」,避免整張列表重建

@Component({
  selector: 'app-list',
  template: `
    <div *ngFor="let item of items; trackBy: trackById">
      {{ item.name }}
    </div>
  `
})
export class ListComponent {
  items: Item[] = [];

  trackById(index: number, item: Item): string {
    return item.id;
  }
}
- 更新其中一項時,只重建那項,其他不動

實作

  1. 為元件加上 OnPush,用 markForCheck() 更新
  2. 大列表加 trackBy 並用 DevTools 對比渲染效能
  3. 用 @Input 傳新物件實作驗證 OnPush 觸發時機

作業

  • 套用 OnPush 並用 markForCheck()
  • 列表用 trackBy 避免整張重建
  • 說出 OnPush 會在哪些時機檢查