23
A Detailed Guide on Angular Onpush Change Detection and Component Design
For all of our favorite projects, we've switched to Angular. We understand what Angular has to offer and how we can use it to create fantastic online applications. However, there are a few things to know about Angular that will help us use it more effectively in our projects.
Because data flow is at the heart while performing everything through Angular, change detection is something to be aware of. It will make it much easier to track out errors and improve our apps when working with large data sets.
Did we ever try to implement the Angular OnPush Change Detection technique in our project but run into some difficult-to-debug bugs and have to revert to the default change detection?
In this article, we’ll look at Angular change detection, data structures, and the process of making them immutable.
When we make a modification to one of our models, Angular recognizes it and updates the views right away. In Angular, this is called change detection. This method aims to ensure that the underlying views and their accompanying models are always in sync. This key component of Angular is what makes it tick, and it's one of the reasons why it's such a good choice for building modern online apps.
Any of the following scenarios can cause an Angular model to change:
- Events in the DOM (click, hover over, etc.)
- Requests made with AJAX
- setTimer() and setInterval() are two methods for setting timers.
All Angular programs are run out of a hierarchical tree of components. During runtime, Angular creates a separate change detector class for each component in the tree, resulting in a hierarchy of change detectors that is equal to the component hierarchy tree.
Angular travels down this tree of change detectors whenever change detection is triggered to see if any of them have reported changes.
Every detected change is subjected to a single change detection cycle, which begins at the root change detector and proceeds down sequentially. Because we know component data can only come from its parent, this sequential design choice is nice because it predictably changes the model.
To report changes to Angular, the change detectors maintain track of the component's historical and current states as well as its structure.
When Angular receives a change detector report, it instructs the appropriate component to re-render and update the document object model (DOM).
Value vs. Reference Types
To comprehend what a change detection strategy is and how it works, we must first comprehend the differences between JavaScript value types and reference types. This part can be skipped if we are already familiar with how this works.
Let's start with a review of the value and reference types, as well as their categories.
Value Types
- Boolean
- Null
- Undefined
- Number
- String
For the sake of simplicity, assume that these types merely store their values in stack memory (which is technically incorrect, but it will suffice for this article). For example, look at the stack memory and its values in the graphic below.
Reference Types
- Arrays
- Objects
- Functions
These types are a little more complicated since they store a reference to their real value on the heap memory in the stack memory. In the sample graphic below, we can see how stack memory and heap memory interact. The stack memory refers to the heap memory's real values for the reference type.
The important difference between value types and reference types is that reading the value of a value type requires only verifying the stack memory, whereas reading the value of a reference type requires first querying the stack memory to obtain a reference, and then using that reference to query the heap memory to locate the reference type's value.
Searching for Reliable Angular Development Company? Your Search ends here.
As previously stated, Angular watches changes to the model to ensure that it captures all of them. It will look for any changes between the previous state of the overall application model and the current state.
Angular raises the following question in the default change detection strategy: Has any value in the model changed? However, with a reference type, we can use strategies to ask a better query. The OnPush change detection method comes into play here.
onPush Strategy
The OnPush technique is based on the notion that treating reference types like immutable objects allows us to notice changes in values much faster. When a reference type is immutable, it indicates that the reference on the stack memory must change every time it is updated. Now we can simply check: Has the reference type's reference (in the stack) changed? If this is the case, double-check all the values (on the heap). If we are having trouble understanding this, go back to the previous stack heap diagrams.
Instead of asking one question, the OnPush approach asks two. Has there been a change in the reference type's reference? Have the values in heap memory changed if this is the case?
Assume we have a 30 element immutable array, and we want to determine if there have been any changes. We know that in order for the immutable array to be updated, the reference to it (in the stack) would have to change. This means we can check to see if the array reference is different right away, potentially saving us 30 more tests (in the heap) to figure out which element is different. The OnPush approach is what it's called.
So, what does it mean to treat reference types as immutable, we might ask? It means we never set a reference type's property, but instead reassign the value as a whole. Take a look at what follows:
Treating objects as mutable:
static mutable() {
var before = {foo: "bar"};
var current = before;
current.foo = "hello";
console.log(before === current);
// => true
}
Treating objects as immutable:
static mutable() {
var before = {foo: "bar"};
var current = before;
current = {foo "hello"};
console.log(before === current);
// => false
}
It's worth noting that in the examples above, we're treating reference types as immutable by convention, so we're still dealing with changeable objects at the end of the day.
So, how do we put an OnPush strategy into action for a component? Simply include the changeDetection argument in their @Component annotation.
import {ChangeDetectionStrategy, Component} from '@angular/core';
@Component({
// ...
changeDetection: ChangeDetectionStrategy.OnPush
})
export class OnPushComponent {
// ...
}
Angular change detection is a built-in framework feature that ensures that a component's data and its HTML template view are always in sync. Change detection determines whether the view of each component has to be updated by recognizing typical browser events like mouse clicks, HTTP requests, and other types of events.
23