0

Angular (precisely: zone.js) monkey-patches functions like setTimeout(), event listeners and similar, in order to fire the Change Detector when the respective callback got executed. However, Angular does not know which objects got updated and which remained unchanged. So, for every property used in the template, Angular has to check whether the property has been changed or not. This does not seem to be a very performant approach.

My question: Why does Angular not use Proxy objects for this? Proxy objects would allow Angular to exactly determine what has been changed, without having to compare the entire state tree. So is there any particular reason why the Angular devs chose not to use Proxy objects (as used in Vue)?

Btw: One advantage of a Proxy object could be that one could call functions in templates without causing additional/unnecessary CD cycles:

<div *ngFor="let item of myFunction()">...</div>
MBuchalik
  • 180
  • 1
  • 8
  • Just a quick tip: calling methods from your template can be very computationally expensive (and it is best to avoid this completely) as the method is called every time change detection runs. In fact, it is called by Angular just to know whether it should run change detection. Check out this post for more info and good luck! https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496 – Stephen Paul May 28 '21 at 15:08
  • That is one of the reasons why a Proxy-based CD would be better than what Angular currently offers. If we had a Proxy-based CD, then we could call functions in the template without making our CD call every function on every cycle. That is what I meant with "One advantage of a Proxy object could be that one could call functions in templates without causing additional/unnecessary CD cycles". – MBuchalik May 28 '21 at 16:05
  • Interesting - I didn't actually realize that Vue supports binding to a method result (or that it is common practice). I'm having a bit of difficulty finding this approach in the documentation for data-binding. https://v1.vuejs.org/guide/syntax.html Do you have any links covering what you describe? – Stephen Paul May 28 '21 at 18:20
  • In Vue, just like in Angular, you can write something like `
    {{ myFunc() }}
    `. And just like in Angular, this is pretty bad, since the method gets called on every re-render. But: Vue also has the concept of Computed Properties. They are similar to ES6 getters. What makes them special: They only get re-evaluated when one of their dependency changes. So a computed propety like `foo() { return this.bar + this.baz }` will only be re-evaluated if `this.bar` or `this.baz` change. Which works because of how Vue utilizes Proxy objects. https://v3.vuejs.org/guide/computed.html
    – MBuchalik May 29 '21 at 09:03
  • I believe that Vue could also have decided to cache method results. At least from a technical point of view, I don't see why they shouldn't have done that. So I assume it is just a design decision. AFAIK, Angular does not have a concept similar to Computed Properties. I assume that, if Angular had a different Change Detection mechanism, then they could actually introduce something like Computed Properties. Additionally, I believe that if Angular used Proxy objects for CD, they could also cache the results of normal method calls. – MBuchalik May 29 '21 at 09:04
  • So to summarize: I might have phrased my point a bit unprecisely. Vue also does not like it if you call methods in the template. But they support Computed Properties. And I am pretty sure that you could technically also extend the caching mechanism to normal method calls as well. – MBuchalik May 29 '21 at 09:06

1 Answers1

0

Because there is a much nicer way to not have to check everything with every change: Observables!

If you use observables together with the async pipe consistently everywhere, Angular will know exactly what changed and when. No need for heavyweight proxies or other things that would emulate this behavior etc.

If you set up your services and pages to only provide observables, it will be as clean as it gets since you can use them directly in HTML.

Furthermore you should also deactivate polling when only using observables. However, I could not find the setting just now (been a while).

Sebastian
  • 5,177
  • 4
  • 30
  • 47
  • That's interesting. So an Angular template is able to re-render when an Observable emits a new value, without having to rely on Zone.js? In that case, one could indeed remove zone.js completely and just use Observables in the template. Wow, that is indeed pretty cool. Still, I am wondering why the Angular devs decided not to use Proxy objects for normal CD. They are maybe not as performant as your approach, but they would at least be better compared to how it is done at the moment. When I first tried Vue, I was shocked :D – MBuchalik May 28 '21 at 16:14