0

I'm working on an angular project, and I need to master change detection so as to make my project usable.

Here is a minimal repro : https://stackblitz.com/edit/angular-3py5bh

<div *ngIf="timeleft$ | async as timeleft"> //countdown (rxjs)
    {{timeleft}}
</div>
<hello></hello> // simulated intensive function

So, basically, I have a main component with a countdown, that refreshes every 0.01s. In this component I have an embedded "hello" component, that includes (in real project) quite intense computations. I simulated these intense computations with a "slow function".

Problem : every time the countdown refreshes (so 100 times/second), the Hello component is refreshed as well, and the "slow function" is called...

As a result, the countdown display is broken (too slow) !!!

I know the answer relies on "change detection", but I'm too new to handle it well. That's why I'm asking for your help !

Thanks a lot !!! Serge

2
  • Zone js is helpful for you. It is available in angular cli projects and run your slow code inside zone . handler.blog.thoughtram.io/angular/2017/02/21/… Commented Nov 14, 2019 at 21:58
  • The problem really lies in doing a method call from within your template. This is really not good practise, as angular has to call this on every detection cycle. Commented Nov 14, 2019 at 22:18

1 Answer 1

1

I would try setting changeDetection: ChangeDetectionStrategy.OnPush on your 'slow' component. This fixes your stackblitz see below:

import { ChangeDetectionStrategy, Component, Input} from '@angular/core';

@Component({
  selector: 'hello',
  template: `<h1>Result : {{mySlowFunction(8)}}!</h1>`,
  styles: [`h1 { font-family: Lato; }`],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class HelloComponent {
  @Input() name: string;

mySlowFunction(baseNumber) {
    let result = 0; 
    for (var i = Math.pow(baseNumber, 7); i >= 0; i--) {        
        result += Math.atan(i) * Math.tan(i) ;
    };
  return result;

}

}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you this is working indeed ! However, when I go back to my real project, I still have the issue : I'm calling an external library ("ng-katex"), inside the "slow component" : <ng-katex>....</ng-katex>. And it seems this external component is being refreshed everytime (even if the parent component is OnPush). How could I "force" ng-katex to be onPush as well?
I would try reading through this link. OnPush should only be used in certain situations and depending on how you're actual application is working it may not work as easy in the stackBlitz. There may be some structural changes you would need to make.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.