25

How to set the default change detection strategy to OnPush? Can it be set globally somehow?

I want to avoid having to adding this line to every component

@Component({
    ...
    changeDetection: ChangeDetectionStrategy.OnPush,
    ...
})
Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
mookie the swede
  • 427
  • 6
  • 13
  • 2
    What about third-party components that depend on ChangeDetectionStrategy.Default strategy? – Estus Flask Jun 14 '16 at 22:05
  • I suppose they should specify CheckAlways if they depend on it...if in fact the default can be changed easily. – mookie the swede Jun 14 '16 at 23:15
  • They wouldn't, because it is framework's default value. I guess you can import your own `Component` that wraps around `ComponenrMetadata` if you really need this behaviour. – Estus Flask Jun 14 '16 at 23:24

3 Answers3

29

It is possible to set the change detection strategy to OnPush in the CLI so that newly generated components will have it set like that.

ng generate component test --changeDetection=OnPush

You can also set that value as default in your angular.json, so that you don't need to set the flag every time:

// angular.json
{
  //...
  "schematics": {
    "@schematics/angular": {
      "component": {
        "changeDetection": "OnPush"
      }
    }
  }
}
ush189
  • 1,342
  • 6
  • 22
  • 30
11

The change detection strategy can only be defined per component or directive not globally.

Using a custom decorator is discouraged because it will not be supported by the upcoming offline template compiler.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Look at next ans, it's possible from cli // angular.json { //... "schematics": { "@schematics/angular": { "component": { "changeDetection": "OnPush" } } } } – Hemant Kumar Singh May 29 '21 at 01:05
0

You don't want it to be set globally. OnPush will never allow change detection to pass unless

  • initial render
  • The component is marked as lViewFlags.dirty

Having OnPush on all components is dangerous unless you really know how Change Detection works.

In short:

  • when something happens in a component (user clicks or any other output is triggered), the view and all its parents is marked as lViewFlags.dirty
  • When an input is set by a parent it is marked as lViewFlags.dirty
  • running markForCheck() wil mark the view and its parents as lViewFlags.dirty

So basically every time something happens the view and its parents is dirty anyway, so there is no performance gain of adding OnPush on top-level components.

I explained it in detail in this article: https://blog.simplified.courses/angular-change-detection-onpush-or-not/

Brecht Billiet
  • 235
  • 1
  • 6