11

As the title says: I'm working on a very big project and in few components I've used ChangeDetectionStrategy.OnPush to avoid bad performances. I was wondering, is it "good" to put in every component that strategy and, in case, use ChangeDetectionRef.detectChanges() to programmatically update the component when needed?

--

That's a small component I have in the app:

 <my-map
    (updatedGeometry)="setUpdatedGeometry($event)"
    [startGraphEdit]="elementToEdit" [startCut]="elementToCut"
    [startCopy]="elementToCopy"
    [updateGraph]="elementToUpdate"
    [showElement]="elementToShow"
    (selectedProfile)="setProfile($event)"
    [reducedChange]="reducedChange"
    (reduceComposer)="setReducedComposer($event)"
    [labelsVisible]="labelsVisible"
    (visibleComposer)="setVisibleComposer($event)"
    [activateLayers]="activeLayers"
    (curLayers)="setCurrentLayers($event)"
    [loadExtent]="extentToLoad"
    (extent)="setExtent($event)"
    [updateZoom]="newZoom"
    (curZoom)="setCurrentZoom($event)"
    (curLon)="setCurrentLon($event)"
    (curLat)="setCurrentLat($event)"
    (poiNotesOffset)="setPoiNotesOffset($event)"
    [cancelPoiNoteCreation]="visibleDetailPanel"
    (poiNoteUpdatedPosition)="setPoiNoteUpdatedPosition($event)"
    [updatePoiNotePosition]="poiNotesElementForUpdate"
    [removePoiNoteElement]="poiNotesElementForDeletion"
    [updatePoiNotes]="updatePoiNotes"
    [projectCode]="prjCode"
    (poiNote)="poiNote($event)"
    [setPrecisionPointerValues]="precisionPointerValues"
    (precisionPointerValues)="updatePrecisionPointer($event)"
    (exploreToolArea)="setExploreToolArea($event)"
    (extentArea)="setExtentArea($event)"
    [exploreToolRadius]="exploreToolRadius"
    (newExploreToolRadius)="setExploreToolRadius($event)"
    [currEnvironment]="currEnvironment"
    (elementSelected)="onElementClick($event)"
    [setaClasses]="classes"
    [height]="mapHeight"
    [width]="mapWidth"
    [offsetX]="mapOffsetX"
    [offsetY]="mapOffsetY"
    [geometriesToHighlight]="geometriesToHighlight"
    [highlightLineElements]="lineElements"
    (poiList)="setPoiList($event)">
  </my-map>

the component has a lot of Input and Output, and also communicate with other components using Subjects and BehaviorSubjects.

Jacopo Sciampi
  • 2,990
  • 1
  • 20
  • 44

3 Answers3

9

ChangeDetectionStrategy.OnPush tells Angular that the component only depends on its @Inputs() and needs to be checked only in the following cases:

The Input reference changes.

An event originated from the component or one of its children.

We run change detection explicitly.

So it depends from your component's content and what you are trying to achieve with it. For example if you are using async pipe for your subscriptions, your component doesn't need ChangeDetectionStrategy.OnPush, because async will do the job automatically. If your component big and uses a lot of data changes, it should contain OnPush strategy, because it will increase your performance, so your whole component code will not run on every changes. If your component small and has only a few properties and methods, or it doesn't contain any subscription or @Input's, or doesn't do any data changes that will happen often, you don't need ChangeDetectionStrategy.OnPush

Artyom Amiryan
  • 2,846
  • 1
  • 10
  • 22
  • Thank you for the reply. I've edited my answer in order to help to understand better my scenario on this project. – Jacopo Sciampi Nov 22 '18 at 08:27
  • @JacopoSciampi if this is your small component, of course you must add `OnPush` strategy, otherwise when your project will rise bigger and bigger, you surely will have performance issues – Artyom Amiryan Nov 22 '18 at 08:30
  • Yep, the main container contains like about 25 others component with input and output, and the `my-map` is one of them. Thank you for your help. – Jacopo Sciampi Nov 22 '18 at 08:32
0

TLDR: NO.

Angular already introduces a lot of complexity to any code, but it gives you back a lot of features, such as change detection. If you remove change detection from Angular, then you are getting all the bad without the good. If you don't have thousands of components in your page, then you won't notice any perceptible improvements in removing change detection.

So:

  • Always use change detection
  • Detach change detection in particular cases, where checking objects deeply can decrease performance in a considerable way
0

Especially with very big projects, the OnPush strategy is recommended to decrease the change detection process that it is a very expensive operation.

With inherited projects, the recommendation is to start applying the OnPush strategy from the leaf components and check that everything is still working.

Only at this point, follow the ancestors and go up one level at time to the root. In the end the overall performance will benefit.

Here there is a very good article about change detection in Angular.

Ferie
  • 1,358
  • 21
  • 36