擴充診斷

Defer 觸發條件設定錯誤

這項診斷會偵測 @defer 區塊中無法到達或多餘的觸發條件。

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

@Component({
  template: `
    @defer (on immediate; on timer(500ms)) {
      <large-component />
    }
  `,
})
class MyComponent {}

這樣寫有什麼問題?

這項診斷會指出 defer 觸發條件設定中幾種有問題的模式,這些模式會導致:

  • 不必要的程式碼:永遠不會影響行為
  • 錯失最佳化機會:無法獲得更好的效能
  • 無法到達的 prefetch 觸發條件:永遠不會執行

會發出警告的情況

這項診斷會標記以下有問題的模式:

immediate 搭配 prefetch 觸發條件

Avoid

prefetch 永遠不會執行

@Component({
  template: `
    @defer (on immediate; prefetch on idle) {
      <my-cmp />
    }
  `,
})
class MyComponent {}
Prefer

移除多餘的 prefetch

@Component({
  template: `
    @defer (on immediate) {
      <my-cmp />
    }
  `,
})
class MyComponent {}

prefetch 計時器沒有比主要計時器更早

Avoid

prefetch 比主要觸發更晚

@Component({
  template: `
    @defer (on timer(100ms); prefetch on timer(3000ms)) {
      <my-cmp />
    }
  `,
})
class MyComponent {}
Avoid

時間相同沒有任何好處

@Component({
  template: `
    @defer (on timer(500ms); prefetch on timer(500ms)) {
      <my-cmp />
    }
  `,
})
class MyComponent {}
Prefer

prefetch 更早觸發

@Component({
  template: `
    @defer (on timer(1000ms); prefetch on timer(500ms)) {
      <large-component />
    }
  `,
})
class MyComponent {}

只有 prefetch、沒有主要觸發條件

Avoid

非預期的提早抓取

@Component({
  template: `
    @defer (prefetch when someFlag()) {
      <heavy-comp />
    }
  `,
})
class MyComponent {
  someFlag = signal(false);
}

這樣的設定可能會讓人以為,prefetch 只會在 someFlag 變成 true 時才執行。然而,由於主要觸發條件仍預設為 on idle,延遲載入的內容可能會在瀏覽器閒置期間更早被抓取,實際上等於繞過了原本預期的條件。

Prefer

明確定義主要觸發條件

@Component({
  template: `
    @defer (on interaction; prefetch when someFlag()) {
      <heavy-comp />
    }
  `,
})
class MyComponent {
  someFlag = signal(false);
}

prefetch 與主要觸發條件完全相同

Avoid

viewport 觸發條件完全相同

@Component({
  template: `
    @defer (on viewport; prefetch on viewport) {
      <my-cmp />
    }
  `,
})
class MyComponent {}
Avoid

interaction 目標完全相同

@Component({
  template: `
    <button #loadBtn>Load</button>
    @defer (on interaction(loadBtn); prefetch on interaction(loadBtn)) {
      <large-component />
    }
  `,
})
class MyComponent {}
Prefer

移除多餘的 prefetch

@Component({
  template: `
    <button #loadBtn>Load</button>
    @defer (on interaction(loadBtn)) {
      <large-component />
    }
  `,
})
class MyComponent {}
Prefer

prefetch 與主要觸發使用不同目標

@Component({
  template: `
    <div #hoverArea>Hover to prefetch</div>
    <button #clickBtn>Click to load</button>
    @defer (on interaction(clickBtn); prefetch on hover(hoverArea)) {
      <large-component />
    }
  `,
})
class MyComponent {}

設定需求

任何擴充診斷要發出訊息,都必須啟用 strictTemplates。 deferTriggerMisconfiguration 除了 strictTemplates 之外,沒有其他額外需求。

如果無法避免,該怎麼辦?

可以透過編輯專案的 tsconfig.json 檔案來停用這項診斷:

{
  "angularCompilerOptions": {
    "extendedDiagnostics": {
      "checks": {
        "deferTriggerMisconfiguration": "suppress"
      }
    }
  }
}

詳情請見擴充診斷設定。