Back to Angular

Defer Trigger Misconfiguration

adev/src/content/reference/extended-diagnostics/NG8021.md

22.0.0-next.104.1 KB
Original Source

Defer Trigger Misconfiguration

This diagnostic detects unreachable or redundant triggers in @defer blocks.

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

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

What's wrong with that?

The diagnostic identifies several problematic patterns in defer trigger configuration that lead to:

  • Unnecessary code that never affects behavior
  • Missed optimization opportunities for better performance
  • Unreachable prefetch triggers that will never execute

Diagnostic warning cases

This diagnostic flags the following problematic patterns:

immediate with prefetch triggers

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

Prefetch timer not earlier than main timer

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

Prefetch without main triggers

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

This configuration may suggest that the prefetch will only run when someFlag becomes true. However, since the main trigger still defaults to on idle, the deferred content can be fetched earlier during the browser’s idle period, effectively bypassing the intended condition.

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

Identical prefetch and main triggers

angular-ts
@Component({
  template: `
    @defer (on viewport; prefetch on viewport) {
      <my-cmp />
    }
  `,
})
class MyComponent {}
angular-ts
@Component({
  template: `
    <button #loadBtn>Load</button>
    @defer (on interaction(loadBtn); prefetch on interaction(loadBtn)) {
      <large-component />
    }
  `,
})
class MyComponent {}
angular-ts
@Component({
  template: `
    <button #loadBtn>Load</button>
    @defer (on interaction(loadBtn)) {
      <large-component />
    }
  `,
})
class MyComponent {}
angular-ts
@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 {}

Configuration requirements

strictTemplates must be enabled for any extended diagnostic to emit. deferTriggerMisconfiguration has no additional requirements beyond strictTemplates.

What if I can't avoid this?

This diagnostic can be disabled by editing the project's tsconfig.json file:

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

See extended diagnostic configuration for more info.