It's good that you pointed out "OnPush" as a change detection strategy but the issue here is calling a function in the middle of your template. You should only use functions when reacting to a DOM event like a button click or emit from another component. Pipes should be used in place of functions in a template to cache the result and only runs once.
a very good video. I worked on angular for 2 years and somehow didn't knew about this issue until I started facing the slowness on one of the pages. Luckily we used clear subscription model on all pages with a central state so we didn't had much trouble with using change detection on push for main pages. Thanks this was great !
great video! what I was missing is what happens if you subscribe without async pipe. one could mention that you have to inject "ChangeDetectorRef" and call its "markForCheck()" to mimic the behaviour of the async pipe. Also I find Angulars name "OnPush" a bit confusing. if i'm not mistaken it does not affect the amount of change detection runs. But it can make each run more light weight by telling angular: "hey, you can skip my component and its children in your current cd-cycle". That you have proven in your example where ngzone events still trigger CD despite OnPush. Awesome Content
Thanks for the video, I'm a backend dev who is getting started in frontend dev, i did a bit of vanilla JS back in like 2013, but i figured i may as well jump right into Angular. I was pulling my hair and getting very frustrated with the UI not updating, backend unexpectedly being called multiple times. The barrier to entry to do proper dev is higher than i expected, like any framework, it hides a bunch of complexity, but the intrinsic complexity just cannot vanish. However I understand that when you grok it, you get much more done than using vanilla JS or TS.
Change detection in Angular highly optimized and for the most apps it is not necessary to use OnPush, unless you have a very lot of components simultaneously on one page. And again, when Angular runs change detection - it's just about checking objects in memory, not re-renrdering, so in most cases it really fast (1-2 ms). Rendering process in browser will be run only if something changed. Using OnPush require you to waste more time while developing. You have to use immutable objects, run change detection manually when you need. It's not so hard, but it is extra job. So, for many projects, this is a premature optimization, which is a bad practice.
You are totally right this is why in small Angular projects on youtube and even in my Angular course I didn't use onPush. But for any big projects it's a must imho.
@@MonsterlessonsAcademy The main thing here is not the size of the project, but the size of each individual page. If your project has hundreds of different pages, this is a very large project. But if, on average, you have only a dozen components on each opened page, then what's the difference how many components there are in total the project. The Chnage Detection will always check only those components that are currently in the component tree.
@@igork555 Yes of course but I never met "simple" big projects. Normally it's some performance things were each ms of calculations matter. For "just pages" we probably don't need spa at all.
@@MonsterlessonsAcademy On top of that, accepted performance is what really matters. Plenty of companies derive value from the speed of development and ease of change rather than the perception of slowness. We all want things to be fast but if the users don't care/can't even see the difference then I'd rather have simpler code
Calling a function to return a date or time at the moment of the call will always return a new date which is always unique and every single comparison will be different. The same is valid for Math.random.
Super video, thank you very much !!! Especially the part with OnPush and the trick with the "checkRender"-Method, i found no other tutorial / answer on stackoverflow, because with OnPush, the ngDoCheck lifecycle hook is still called, but the html is not rendered again, if there is no change. Furthermore i finally understood the ...-spread operator, and the importance of immutability.
You're welcome! I searched really long for checkRender as I wanted to really see how many times html is rendered. Dunno why people don't look for it. In React we get it out of the box...
Should we always assign onPush as the strategy for all our components? Just in case we don’t want any new component of ours to update automatically under the change detection cycle? If so, why isn’t this the default strategy in Angular?
Yes it is recommened to put onPush everywhere. There are lots of eslint configuration which recommend this rule. It is not default (probably) so it just works for beginners even if it is less performant.
Hi, thanks a lot for your video. I need to optimize my angular app, so I want to reduce chenge detection cycles. Is there a way to track components/views that trigger change detection? I tried with Angular DevTools of Chrome, but it is not detailed
Is it true you can just put the onPush in your main app.component file and it cascades down to all other components? Or would I have to put on it on manually to each component separately?
OnPush means that change detection won't run for a component if its inputs don't change. The fact that CD is not run for children is a side-effect, because CD is not run for a parent, it's not executed for children. But if you have CD executed for a parent, it will run for it's children, unless they are also OnPush
Why onPush stategy is not default? I read several articles and still I don't know. Haven't found valueable answer yet. If onPush is not default is it has some drawbacks?
That's a great question. I would like to see it by default or at least configurable globally. The only way is to configure eslint to show warnings if you don't write it. I think it is not by default so as people must understand more about how things are working. With Angular default behaivour it just rerenders every time and works.
Did some changes to a app that handles 5 editable tables simultaneously. Changed most components to OnPush and changed function calls to pipes or in some cases to a precalculated value in vm, it was a massive performance upgrade. Previously it had a function that change style of each editable cell which was called 3500 times every time anything changed with a table of only 30 rows! Now it's barely called at all. What i didn't know from this video is that async work with OnPush! Will be looking into using that more. Thanks for a awesome video!
I didn't expect the definition of OnPush strategy on your channel. Good work! But i'm confused about this. So, when object is passing down through change detection hierarchy (from parent to child, from list of todos to todo) default behaviour is that it passes objects via references. And when those references are passed it'll update those variables. Every time when object passing down through @Input will be updated. That is the default behaviour. Now, if we change to OnPush Strategy then object passed by reference won't be updated on the view and we have to copy them. And, if we copy them, it will takes more space in the memory! So how it is helpful with performance? From my point of view, the application will be slower, because of browser will take more space to work. What am i missing? :D Also, i don't like that i need to manually copy those objects (but that is my preference, not performance thing per se ) for every @Input() value. Um, maybe there are some decorators which are handling that copying so the developer doesn't take care about using rest operator or Object.assign to make deep copy of the object. That would be helpful. But i didn't heard anything about it, since few years, so it seems impossible to achieve that. I wonder why...
Making JS copies is not that expensive and Javascript is fast. Making checks for changes and rerendering DOM is slow and takes time and performance. Realistically mutability is bad for debugging, code safety etc. I recommend everybody to learn how to write pure, functional code as it improves all this things significantly.
@@MonsterlessonsAcademy what I meant it would have been logical part of the topic to consider. Since almost every arrangement of using reactive variables is shown - that one is missing. What would happen then? Is it the exactly the same as async pipe? Not obvious for a beginner
Good explanation. Can we simply assume that better all child components which has input decorator must rely on OnPush strategy? It takes more time as we should use immutable operations but it will increase performance as project grows.
This also tells me that there's nothing wrong by executing a function in the template if you're using onPush and you know what are you doing, am I right? Cuz I saw a lot of articles that say that Angular will re-execute the function because of the re-renders but they don't know why the Angular component re-renders so much. Excellent video. Best explanation of this that I found.
There is nothing wrong to do anything if you know what you are doing :) I still try to avoid calling functions in template directly but it is not always possible.
1) ExpressionChangedAfterItHasBeenCheckedError error won't affect in PROD, right? So Can I skip the error in DEV also even it throws in console? 2) why the Angular again check the Change Detection 2nd time in DEV mode? 3) why the Angular doesn't check the Change Detection 2nd time in PROD mode?
1. Yes it's in dev only. The error says that you have a problem in your application. I would better fix it :) 2. to be sure that things don't change. With math.random or time.now they will change for example 3. because it's a dev tool to find bugs in your application.
@@MonsterlessonsAcademy Thanks for trying to help me out to clear the clouds. :) 1. Partially agreed, bcoz, it's displaying the updated values in view(It's my need), even it throws the error. 2. I don't agree: What's the problem for Angular if the value is changing once it's checked. Why it's allowing if I add cdf.detectChanges() or settimeout(). Why I shouldn't update values in ngAfterViewInit() & ngOnChanges(), what's the purpose actually to not do in the both lifecycles? 3. AGREED.
@ThiruMani Theivarajan I didn't say that you should not use ngAfterViewInit or ngOnChanges. But all times when angular screamed about this error it was my architectural fault and not angular. I use both ngAfterViewInit or ngOnChanges without triggering this error.
@@MonsterlessonsAcademy Hi, I'm questioning against Angular only not at you, please do not mistake me, you are one of my best guider. And I'm getting confused about the purpose only. So it's Angular architectural fault, so they provided the workaround with the changeDetectorRef, settimeout. Right?
No worries. It's difficult to offence me :) I don't think it's Angular architectural fault but it's a notification that you do something incorrect with the way how angular works. You might see it like a framework fault but it's the way how it was intended to be built. setTimeout looks for sure like a hack for me. But changeDetectorRef is a way to manually trigger detection changes of the framework.
Wow thanks this is one of those rare topics! So glad you made it available on RUclips. One question, I've tried in in my own application and I realised when I applied the change detection strategy on app.component it works for all the nested components which does not require me to implement it on all the other components. Is the right way to do it? Or should we implement on selective components? Thanks!
Hi it is not. You need to write OnPush in every component. If you enable angular linting rules for your project you will get this error in every single component.
@@MonsterlessonsAcademy Thanks for the prompt reply; I have bought your Monster Lesson - Angular and NgRx - Building Real Project From Scratch, and I've realized that you did not implement the change detection in the lesson. I there a use case where change detection is not necessary, or it a best practice to complement it on every component? Thank you so much for your guidance. Cheers!
@@dinysanchez there are 2 possible ways. Some people like to write push in every component from the start and some people like to start optimizing if we have performance problems. If the whole app is not slow then I won't optimize it.
@@MonsterlessonsAcademy Noted. Thank you for your insight. I do enjoy you Angular tutorial please make more especially on Angular Reactive Forms. Cheers!
WATCH NEXT: Angular Interview Questions and Answers - Dominate Your Next Interview - ruclips.net/video/5A_YKlVWMPo/видео.htmlsi=2DCn7yspEAAJ2H6l
I've been doing Angular for 7 years and learned a lot from this video. There is just so much to know when it comes to Angular.
Yeap. The level of entrance is enormous.
It's good that you pointed out "OnPush" as a change detection strategy but the issue here is calling a function in the middle of your template. You should only use functions when reacting to a DOM event like a button click or emit from another component. Pipes should be used in place of functions in a template to cache the result and only runs once.
I agree with you
a very good video. I worked on angular for 2 years and somehow didn't knew about this issue until I started facing the slowness on one of the pages. Luckily we used clear subscription model on all pages with a central state so we didn't had much trouble with using change detection on push for main pages. Thanks this was great !
Glad it helped!
Thank God finally I found channel who is good in Angular, and write code using Vim. I ma hit that bell so hard
Simple and easy to understand! Gonna have to go through your channel and learn more, thanks!
Awesome, thank you!
great video! what I was missing is what happens if you subscribe without async pipe. one could mention that you have to inject "ChangeDetectorRef" and call its "markForCheck()" to mimic the behaviour of the async pipe. Also I find Angulars name "OnPush" a bit confusing. if i'm not mistaken it does not affect the amount of change detection runs. But it can make each run more light weight by telling angular: "hey, you can skip my component and its children in your current cd-cycle". That you have proven in your example where ngzone events still trigger CD despite OnPush. Awesome Content
Yes OnPush doesn't skip the digest cycle. It is kind of hack as the whole digest cycle doesn't know what was changed and what to check.
Thank you so much for this! I'm new to Angular and this video helped me quickly resolve a bug I've been working since 2 days. Cheers to you!
Glad it helped!
Thanks for the video, I'm a backend dev who is getting started in frontend dev, i did a bit of vanilla JS back in like 2013, but i figured i may as well jump right into Angular. I was pulling my hair and getting very frustrated with the UI not updating, backend unexpectedly being called multiple times. The barrier to entry to do proper dev is higher than i expected, like any framework, it hides a bunch of complexity, but the intrinsic complexity just cannot vanish. However I understand that when you grok it, you get much more done than using vanilla JS or TS.
Yeap
Change detection in Angular highly optimized and for the most apps it is not necessary to use OnPush, unless you have a very lot of components simultaneously on one page. And again, when Angular runs change detection - it's just about checking objects in memory, not re-renrdering, so in most cases it really fast (1-2 ms). Rendering process in browser will be run only if something changed.
Using OnPush require you to waste more time while developing. You have to use immutable objects, run change detection manually when you need. It's not so hard, but it is extra job. So, for many projects, this is a premature optimization, which is a bad practice.
You are totally right this is why in small Angular projects on youtube and even in my Angular course I didn't use onPush. But for any big projects it's a must imho.
@@MonsterlessonsAcademy The main thing here is not the size of the project, but the size of each individual page. If your project has hundreds of different pages, this is a very large project. But if, on average, you have only a dozen components on each opened page, then what's the difference how many components there are in total the project. The Chnage Detection will always check only those components that are currently in the component tree.
@@igork555 Yes of course but I never met "simple" big projects. Normally it's some performance things were each ms of calculations matter. For "just pages" we probably don't need spa at all.
@@MonsterlessonsAcademy On top of that, accepted performance is what really matters. Plenty of companies derive value from the speed of development and ease of change rather than the perception of slowness. We all want things to be fast but if the users don't care/can't even see the difference then I'd rather have simpler code
The best and thorough explanation of the change detection, thank a lot!
Glad it was helpful!
Great video. have question about the "time now " mentioned at 4:30 . Couldn't understand the point. could you elaborate?
Calling a function to return a date or time at the moment of the call will always return a new date which is always unique and every single comparison will be different. The same is valid for Math.random.
I love your channel when I watch your videos I learn new things every time.
Happy to hear that!
Thanks! Your videos are so incredibly helpful
Thank you so much for your support! It means a lot to me.
Love your videos, thanks for this one! 🤘
Thanks!
Dude you're videos are gold. I've learned so much from them. Thanks a lot from the bottom of my heart! And plz keep making more :)
Glad you like them!
Amazing content. I finally understood change detection. Thanks so much!
Glad it helped!
Crisp and Clear Explaination! Thank You
Glad it was helpful!
Thank you for the video. Very insightful
Glad it was helpful!
Really, the best angular helper
Thanks!
You are the best!!! Any webpage to buy your course?
Thanks. monsterlessons-academy.com/courses
good stuff!!! but i miss the comparison of performance or explanations when to use async and when change detection push. thank you in advance!
This are 2 different things which are not related to each other. You should use both.
Super video, thank you very much !!! Especially the part with OnPush and the trick with the "checkRender"-Method, i found no other tutorial / answer on stackoverflow, because with OnPush, the ngDoCheck lifecycle hook is still called, but the html is not rendered again, if there is no change. Furthermore i finally understood the ...-spread operator, and the importance of immutability.
You're welcome! I searched really long for checkRender as I wanted to really see how many times html is rendered. Dunno why people don't look for it. In React we get it out of the box...
Thanks. Very nice, clean and clear explanation!
Glad it was helpful!
Nice explanation! Thank you
You are welcome!
Very well explained! Thanks.
Glad it was helpful!
Should we always assign onPush as the strategy for all our components? Just in case we don’t want any new component of ours to update automatically under the change detection cycle? If so, why isn’t this the default strategy in Angular?
Yes it is recommened to put onPush everywhere. There are lots of eslint configuration which recommend this rule. It is not default (probably) so it just works for beginners even if it is less performant.
Do you think the onPush Strategy is till relevant after signals are out?
If you use just signals no. If you use streams yes
@@MonsterlessonsAcademy make sense :)
Thanks for the answer.
It was helpful! Thank you
You're welcome!
Great video man!! Can you post more advanced angular concepts ?? Thanks
Thank you! I will add the idea to the list of future videos.
Thanks for the detailed explanation!
My pleasure!
Hi, thanks a lot for your video. I need to optimize my angular app, so I want to reduce chenge detection cycles. Is there a way to track components/views that trigger change detection? I tried with Angular DevTools of Chrome, but it is not detailed
Not that I know of. I typically do that manually for every component.
Superb explanation 👍🏻
Thank you 🙂
Yaaay, I found non-indian guy's video about change-detection.... :D
That means indian guys are doing a better job :D
@@MonsterlessonsAcademy they are not that better. Only with basic things. For Advance Concepts Western People are good
@@sportscompilation2218 i Agee
You are racist or what mother fck
Is it true you can just put the onPush in your main app.component file and it cascades down to all other components? Or would I have to put on it on manually to each component separately?
OnPush means that change detection won't run for a component if its inputs don't change. The fact that CD is not run for children is a side-effect, because CD is not run for a parent, it's not executed for children. But if you have CD executed for a parent, it will run for it's children, unless they are also OnPush
That is why Computed properties in Vue are so valuable
Yes exactly. Thats why I'm a huge fan of computed properties in any framework.
nice topic and nice explanation
Thanks a lot!
Great video. Congratulations and thank you very much.
Thank you very much!
Nice explanation. When should we use markForCheck and detectChanges method?
markForCheck marks it for the next digest cycle and detectChanges triggers digest cycle.
You are really good at explaining. Keep up with the good work
Thanks, will do!
I love this video it's great your way of explaining this concept
Glad to hear that!
Good explanation but what’s missing here ist changing non-input values. Common use case where you have to use ChangeDetectorRef
I'm not sure what to explain here. Every time when you want change detection but it was not triggered because of onPush you write cdr.detectChanges()
Why onPush stategy is not default? I read several articles and still I don't know. Haven't found valueable answer yet. If onPush is not default is it has some drawbacks?
That's a great question. I would like to see it by default or at least configurable globally. The only way is to configure eslint to show warnings if you don't write it.
I think it is not by default so as people must understand more about how things are working. With Angular default behaivour it just rerenders every time and works.
I'm using trackbyFn for ngfors because only its changing the row of change row. What do you think about the trackbyfn for performance?
It is recommended to use trackBy always in any case. This is why it is a recommended rule in all linters.
soft is rather complex.. sotNice tutorialngs more than they should be. But you've made a great job explaining it!
Glad it was helpful!
Good Explaination!
Thanks!
How to fix detection change happened before the value changed?! I hate this error
Debug why your value changed when Angular checks it immediately after first check. It's typically a bug on your side.
What an amazing video. Thanks a lot!
Glad you liked it!
keep it up u r insanlly good 💜
Thank you, I will
I assume that the '20x' is a synonim to 'a lot'?
Yeap
Did some changes to a app that handles 5 editable tables simultaneously. Changed most components to OnPush and changed function calls to pipes or in some cases to a precalculated value in vm, it was a massive performance upgrade. Previously it had a function that change style of each editable cell which was called 3500 times every time anything changed with a table of only 30 rows! Now it's barely called at all.
What i didn't know from this video is that async work with OnPush! Will be looking into using that more. Thanks for a awesome video!
Glad to hear that!
Very nice!
Thanks!
I didn't expect the definition of OnPush strategy on your channel. Good work!
But i'm confused about this.
So, when object is passing down through change detection hierarchy (from parent to child, from list of todos to todo) default behaviour is that it passes objects via references. And when those references are passed it'll update those variables. Every time when object passing down through @Input will be updated. That is the default behaviour.
Now, if we change to OnPush Strategy then object passed by reference won't be updated on the view and we have to copy them. And, if we copy them, it will takes more space in the memory!
So how it is helpful with performance?
From my point of view, the application will be slower, because of browser will take more space to work.
What am i missing? :D
Also, i don't like that i need to manually copy those objects (but that is my preference, not performance thing per se ) for every @Input() value. Um, maybe there are some decorators which are handling that copying so the developer doesn't take care about using rest operator or Object.assign to make deep copy of the object. That would be helpful. But i didn't heard anything about it, since few years, so it seems impossible to achieve that. I wonder why...
Making JS copies is not that expensive and Javascript is fast. Making checks for changes and rerendering DOM is slow and takes time and performance.
Realistically mutability is bad for debugging, code safety etc. I recommend everybody to learn how to write pure, functional code as it improves all this things significantly.
great video!!
Glad you liked it!
I enjoyed the material, but I will say that the terminal editor made it harder for me to follow what file you were working on and why.
There is a file name at the bottom left and there is source code in the description that you can check.
The one example is missing: subscribing to observable in onInit and setting component variable and then using it in template
But it doesn't solve anything. You still create a subscription and you must unsubscribe later.
@@MonsterlessonsAcademy what I meant it would have been logical part of the topic to consider. Since almost every arrangement of using reactive variables is shown - that one is missing. What would happen then? Is it the exactly the same as async pipe? Not obvious for a beginner
Good explanation. Can we simply assume that better all child components which has input decorator must rely on OnPush strategy? It takes more time as we should use immutable operations but it will increase performance as project grows.
Yes, I typically do all components in the app with OnPush
Thank you. This is good to know.
This also tells me that there's nothing wrong by executing a function in the template if you're using onPush and you know what are you doing, am I right? Cuz I saw a lot of articles that say that Angular will re-execute the function because of the re-renders but they don't know why the Angular component re-renders so much.
Excellent video. Best explanation of this that I found.
There is nothing wrong to do anything if you know what you are doing :) I still try to avoid calling functions in template directly but it is not always possible.
@@MonsterlessonsAcademy can you give example what is executing function in the middle of template
How do you know it's 20 times faster? How can you quantify the amount of time not having so many change cycles has?
It's a clickbaity title. But you can profile your app with chrome performance tools.
1) ExpressionChangedAfterItHasBeenCheckedError error won't affect in PROD, right? So Can I skip the error in DEV also even it throws in console?
2) why the Angular again check the Change Detection 2nd time in DEV mode?
3) why the Angular doesn't check the Change Detection 2nd time in PROD mode?
1. Yes it's in dev only. The error says that you have a problem in your application. I would better fix it :)
2. to be sure that things don't change. With math.random or time.now they will change for example
3. because it's a dev tool to find bugs in your application.
@@MonsterlessonsAcademy
Thanks for trying to help me out to clear the clouds. :)
1. Partially agreed, bcoz, it's displaying the updated values in view(It's my need), even it throws the error.
2. I don't agree: What's the problem for Angular if the value is changing once it's checked. Why it's allowing if I add cdf.detectChanges() or settimeout().
Why I shouldn't update values in ngAfterViewInit() & ngOnChanges(), what's the purpose actually to not do in the both lifecycles?
3. AGREED.
@ThiruMani Theivarajan I didn't say that you should not use ngAfterViewInit or ngOnChanges. But all times when angular screamed about this error it was my architectural fault and not angular. I use both ngAfterViewInit or ngOnChanges without triggering this error.
@@MonsterlessonsAcademy
Hi, I'm questioning against Angular only not at you, please do not mistake me, you are one of my best guider. And I'm getting confused about the purpose only.
So it's Angular architectural fault, so they provided the workaround with the changeDetectorRef, settimeout. Right?
No worries. It's difficult to offence me :) I don't think it's Angular architectural fault but it's a notification that you do something incorrect with the way how angular works. You might see it like a framework fault but it's the way how it was intended to be built. setTimeout looks for sure like a hack for me. But changeDetectorRef is a way to manually trigger detection changes of the framework.
hey , i swear i love you so much
Thanks!
for change detection error I mostly use observable so angular dont give errors
This is a nice way as you can fully define how you cache property and when change should be triggered.
Masterpice! Also I enjoy of react in udemy.
I'm happy to hear that!
Shouldn't the title say Your project instead of You project?
Yeap. Missed the letter
Many thanks 👍
Welcome 👍
Spasibo
thanks 😀
You're welcome!
i think that the signals have solved this easily.
Yes exactly this is why starting from ng16 it makes a lot of sense to use them.
@@MonsterlessonsAcademy yeeeh, you are a good searcher . search about islam religion ❤️.
Thank you
You're welcome!
please, is posible to add subtitles in english to your videos, i don't understand very well your english 🙂
Unfortunately not as I don't create subtitles by hands.
Hey Michael, thanks for tNice tutorials, I want to make a one off donation to you - give the details
Signals, baby
Yeap
You❌ Your✅
it is a shame i cant add this video to my favorite's list. idk why youtube marks these videos as 'for kids', which removes this feature.
Strange. It shows "not for kids' when I'm editing the video.
Slow down and pace yourself. You're talking way too fast. You should also quickly introduce yourself in all videos.
Wow thanks this is one of those rare topics! So glad you made it available on RUclips. One question, I've tried in in my own application and I realised when I applied the change detection strategy on app.component it works for all the nested components which does not require me to implement it on all the other components.
Is the right way to do it? Or should we implement on selective components?
Thanks!
Hi it is not. You need to write OnPush in every component. If you enable angular linting rules for your project you will get this error in every single component.
@@MonsterlessonsAcademy Thanks for the prompt reply; I have bought your Monster Lesson - Angular and NgRx - Building Real Project From Scratch, and I've realized that you did not implement the change detection in the lesson. I there a use case where change detection is not necessary, or it a best practice to complement it on every component? Thank you so much for your guidance. Cheers!
@@dinysanchez there are 2 possible ways. Some people like to write push in every component from the start and some people like to start optimizing if we have performance problems. If the whole app is not slow then I won't optimize it.
@@MonsterlessonsAcademy Noted. Thank you for your insight. I do enjoy you Angular tutorial please make more especially on Angular Reactive Forms. Cheers!