I have a component that displays dynamic, read-only data. For example:
<div>{{getText()}}</div>
I noticed that getText is being invoked over and over by Angular, even if there is seemingly no need to do so, i.e. no data has changed. How can I detect when Angular triggers view refresh?
2
Answers
You can detect it using the
ngDoCheck
hook. Which fires during a change detection cycle.On each cycle the function gets called and the function is evaluated.
If you want to improve performance, you can enable ChangeDetectionStrategy.OnPush, which will reduce the number of change detection cycles.
Angular OnPush Change Detection and Component Design – Avoid Common Pitfalls
The more easier solution is to evaluate the function and store it in a property which you show in HTML, then you can rerun the function to update the property whenever it will change.
export class SomeComponent {
@Input() conditionToUpdateText: string;
displayProp = ”;
In the above example we set the initial value of
displayProp
on thengOnInit
hook (during initialization), then since the data is dependent on the inputs, we use thengOnChanges
hook ( when inputs change ) to reevaluate the property. The HTML usage will be:Although it is ok for simple functions to fire multiple times during change detection, as a rule of thumb avoid functions since if you accidentally use a costly array operation like
find
in the HTML binding, it gets called multiple times and causes a drop in performance.This is expected – on every change detection cycle all expressions in the template are re-evaluated. There is one other approach which is not mentioned in the other answer. You can use Signals instead, which allow fine-grained reactivity and avoids unnecessary computations.
To give an example:
This example uses the new signal-based
input()
function and computes atext
based on the input value, using acomputed
function. Here, the computation for the text is only performed if one of the signals inside the computed function changed their value, which avoids unnecessary computations.Finally, you can display the text in the template like the following: