Pretty good article, especially in regards to the $digest cycle which can cause some performance migraines. This is something I have seen newbies in Angular encounter pretty quickly, too many watchers and mistakenly triggering tonnes of $digest cycles.
Regarding point 7.1 - sometimes in my experience, an application might have many elements inside of an ng-repeat which cannot be avoided. It is one thing to say keep your lists small, but when you're dealing with a whole bunch of data that is loaded in via an infinite scroll, you can't just stop the content at 50 results.
Honestly, the only solution the team I currently work with have come up with is using React.js (swapping out Angular for React completely would be too expensive). If you take the heavy UI work away from Angular and use React.js, it honestly makes your lives easier. Even just for rendering a whole lot of content inside of an ng-repeat, you will see the performance issues vanish. Using track by in your ng-loops will also save you more migraines.
Don't get me wrong, Angular without-a-doubt has some issues, but there hasn't really been an issue that the team hasn't been able to work around so far. Most issues you encounter in Angular are caused by a limited understanding of the framework and its strengths. The documentation is pretty bad, but you find the more you use Angular, the better you get at it.
Most of the limitations you encounter in Angular, they are in every single other front-end framework as well. This is because browsers currently do not support some of the niceties in ES6 and many of us have to support older browsers like IE9, etc. But even so, ES6 won't fix everything, but it will make things a lot less painful. Things are getting better, but front-end frameworks are just a little too ahead of their time at the moment.
While Angular has issues now with performance (mainly two way binding and watching) when ES6 is supported in Angular 2.0 and object.observe() is used, we are going to see a dramatically more powerful framework without all of the dirty checking Angular currently has to make binding and watching work. This will be the case for other frameworks like Knockout and Ember as well.
Yeah, I had the same experience (except using Mithril instead of React).
Am I the only one not holding my breath for Object.observe? I see people mention it so casually, but the fact is it's still a long way from being anywhere close to production ready[1]
We'ere using KnockoutJS, not Angular in our app, and it suffers from the same issues. On certain components, especially when applying complex rendering logic, that need to be optimized, like our DataGrids, we've been moving towards a React-based rending flow (might eventually do it serverside). The React version is about 8x faster than our Knockout implementation.
The angular core team has mentioned that they may have overstated the performance gains of Object.observe(). I don't think there'll be as large performance gains as people think.
Even once it's widely available, it'll probably take a long time to optimize.
On a personal note, after using angular for around two years... You can write good angular code, but in my experience, a lot of people (especially libraries) are writing really bad stuff. I've been playing around with this whole Flux+React ecosystem and I'm starting to think the patterns it presents are more sensible.
On top of that, this whole magic of two-way data-binding is certainly cool and fun, but I noticed that for most cases I know exactly when a value is changing, so notifying of a change manually is not a big deal (even if it's more work, it usually brings good performance). I'd be really happy if angular had a built-in way of doing something like event-based bindings. Right now we have regular bindings, and one-time bindings. I want a way to bind to a property where it'll wait for the property to stabilize and then remove the watcher unless I manually notify it that it changed.
So here's a trivial example: let's say I have a Stack Overflow styled app. When I open a post, it'll load the title, question, and answers. Now I could use one-time bindings so the title and question aren't being watched anymore. But I know that after loading this page I could receive a websocket notification that the title has been updated. I'm going to have to keep a watcher on the title even though it can only change in that one condition! It'd be great to just have something built in to handle this. (And I can think of many ways to solve this, such as making my own directive in which I add a listener for an event and then update it manually; but it'd be great if we had a built-in solution.)
That is actually a great idea. Things are a little busy in the lead up to the holidays, but perhaps in the New Year, we could write up a little article detailing the quirks we encountered and how we fixed them. We have learned a lot of the last year or so.
If you could show some example of views before and after optimization, that would be great! I haven't yet had to sit down and optimize beyond basic best practices so it would be valuable to see some actual coded, real world example.
Not everyone has the luxury of throwing away one years worth of work and choosing something else.
Once you understand how Angular works internally and not just in a tutorial sense, it can be very powerful. Most of Angular's quirks can be worked around using common sense, and as in some cases, using the right tools, understanding Angular isn't a silver bullet goes a long way too. The issues my team encountered won't be encountered by everyone, we were dealing with potentially thousands of items being in the page caused by infinite scrolling.
I get that some people think Angular is difficult, learning the basics is easy, learning how to use Angular the right way is the hard part. I think a lot of the issues people encounter using Angular are due to their own limited understanding of the framework. The documentation leaves a lot to be desired, but there are a lot of good blog posts out there like this which tell you upfront the issues and best practices.
The beautiful thing about Angular is that it is not difficult to get it to shows its warts, so you can work around or fix them. Combined with Batarang, you can get a pretty insightful look into your application and where you can improve it as well. A lot of the issues we've encountered were due to the fact someone on the team did something wrong expecting it to work, not Angular itself. Like a good woodworker, you've got to go with the grain, not against it.
I think if our application were being built from the ground up today, the team unanimously agrees that we would use something like React + Flux. But in our case, the business wouldn't be too happy with us throwing away old unit tested and battle-tested code in favour of something new and lean for the sake of a few milliseconds of browser performance.
I agree 100% with this. Every framework has its pain points - that is why it limits you as a framework, as opposed to homerolling your own solution.
The gain you get is better support for foundational tasks and the ability to focus on the high level business requirements faster. There are very smart people working on the teams of all of these frameworks, available for free with an MIT license and supported for free - take advantage of it, but don't expect any of them to be perfect and expect to still be putting in hard work in understanding the internals of all of them.
There are very smart people working on the teams of all of these frameworks
Dunno, most of the JS frameworks have crappy design and mediocre implementations. Angular is not some shining beacon, it's convoluted beyond belief.
Being a framework, and being from a large company doesn't mean much, nor it guarantees that the result reflects having been worked by "smart people".
The SUN people were smart too, and yet we got the J2EE shit-fest of early to mid 00's. IBM also shipped it's share of crappy frameworks, Microsoft too.
and expect to still be putting in hard work in understanding the internals of all of them.
Also expect those framework based skills to be obsolete 4-5 years down the line, when some other shiny framework comes along.
Also expect to have to rewrite tons of your work, when the developers with ADD lose interest and go to rewrite the framework, like with Angular 2 (and I've relived these all over again with (Java) Struts 2, (Python) Zope 3, and tons of other stuff besides).
Comments
Pretty good article, especially in regards to the $digest cycle which can cause some performance migraines. This is something I have seen newbies in Angular encounter pretty quickly, too many watchers and mistakenly triggering tonnes of $digest cycles.
Regarding point 7.1 - sometimes in my experience, an application might have many elements inside of an ng-repeat which cannot be avoided. It is one thing to say keep your lists small, but when you're dealing with a whole bunch of data that is loaded in via an infinite scroll, you can't just stop the content at 50 results.
Honestly, the only solution the team I currently work with have come up with is using React.js (swapping out Angular for React completely would be too expensive). If you take the heavy UI work away from Angular and use React.js, it honestly makes your lives easier. Even just for rendering a whole lot of content inside of an ng-repeat, you will see the performance issues vanish. Using track by in your ng-loops will also save you more migraines.
Don't get me wrong, Angular without-a-doubt has some issues, but there hasn't really been an issue that the team hasn't been able to work around so far. Most issues you encounter in Angular are caused by a limited understanding of the framework and its strengths. The documentation is pretty bad, but you find the more you use Angular, the better you get at it.
Most of the limitations you encounter in Angular, they are in every single other front-end framework as well. This is because browsers currently do not support some of the niceties in ES6 and many of us have to support older browsers like IE9, etc. But even so, ES6 won't fix everything, but it will make things a lot less painful. Things are getting better, but front-end frameworks are just a little too ahead of their time at the moment.
While Angular has issues now with performance (mainly two way binding and watching) when ES6 is supported in Angular 2.0 and object.observe() is used, we are going to see a dramatically more powerful framework without all of the dirty checking Angular currently has to make binding and watching work. This will be the case for other frameworks like Knockout and Ember as well.
Yeah, I had the same experience (except using Mithril instead of React).
Am I the only one not holding my breath for Object.observe? I see people mention it so casually, but the fact is it's still a long way from being anywhere close to production ready[1]
[1](http://kangax.github.io/compat-table/es7/#Object.observe)
We'ere using KnockoutJS, not Angular in our app, and it suffers from the same issues. On certain components, especially when applying complex rendering logic, that need to be optimized, like our DataGrids, we've been moving towards a React-based rending flow (might eventually do it serverside). The React version is about 8x faster than our Knockout implementation.
The angular core team has mentioned that they may have overstated the performance gains of Object.observe(). I don't think there'll be as large performance gains as people think.
Even once it's widely available, it'll probably take a long time to optimize.
There's a discussion about it here: https://github.com/angular/angular.js/issues/3601
On a personal note, after using angular for around two years... You can write good angular code, but in my experience, a lot of people (especially libraries) are writing really bad stuff. I've been playing around with this whole Flux+React ecosystem and I'm starting to think the patterns it presents are more sensible.
On top of that, this whole magic of two-way data-binding is certainly cool and fun, but I noticed that for most cases I know exactly when a value is changing, so notifying of a change manually is not a big deal (even if it's more work, it usually brings good performance). I'd be really happy if angular had a built-in way of doing something like event-based bindings. Right now we have regular bindings, and one-time bindings. I want a way to bind to a property where it'll wait for the property to stabilize and then remove the watcher unless I manually notify it that it changed.
So here's a trivial example: let's say I have a Stack Overflow styled app. When I open a post, it'll load the title, question, and answers. Now I could use one-time bindings so the title and question aren't being watched anymore. But I know that after loading this page I could receive a websocket notification that the title has been updated. I'm going to have to keep a watcher on the title even though it can only change in that one condition! It'd be great to just have something built in to handle this. (And I can think of many ways to solve this, such as making my own directive in which I add a listener for an event and then update it manually; but it'd be great if we had a built-in solution.)
What about a blog post about all the things you guys learned using Angular? It would be very interesting.
That is actually a great idea. Things are a little busy in the lead up to the holidays, but perhaps in the New Year, we could write up a little article detailing the quirks we encountered and how we fixed them. We have learned a lot of the last year or so.
If you could show some example of views before and after optimization, that would be great! I haven't yet had to sit down and optimize beyond basic best practices so it would be valuable to see some actual coded, real world example.
Awesome. I am planning a Huge JSF to Angular.JS migration next year and that would be a very nice read.
Please let me know when you do it.
We managed to get a twenty percent speed up in our app that used Angular...
...by removing it and using something bespoke and lean and simple instead!
Not everyone has the luxury of throwing away one years worth of work and choosing something else.
Once you understand how Angular works internally and not just in a tutorial sense, it can be very powerful. Most of Angular's quirks can be worked around using common sense, and as in some cases, using the right tools, understanding Angular isn't a silver bullet goes a long way too. The issues my team encountered won't be encountered by everyone, we were dealing with potentially thousands of items being in the page caused by infinite scrolling.
I get that some people think Angular is difficult, learning the basics is easy, learning how to use Angular the right way is the hard part. I think a lot of the issues people encounter using Angular are due to their own limited understanding of the framework. The documentation leaves a lot to be desired, but there are a lot of good blog posts out there like this which tell you upfront the issues and best practices.
The beautiful thing about Angular is that it is not difficult to get it to shows its warts, so you can work around or fix them. Combined with Batarang, you can get a pretty insightful look into your application and where you can improve it as well. A lot of the issues we've encountered were due to the fact someone on the team did something wrong expecting it to work, not Angular itself. Like a good woodworker, you've got to go with the grain, not against it.
I think if our application were being built from the ground up today, the team unanimously agrees that we would use something like React + Flux. But in our case, the business wouldn't be too happy with us throwing away old unit tested and battle-tested code in favour of something new and lean for the sake of a few milliseconds of browser performance.
Also known as the "sunk cost falacy": we've invested so much in working with the wrong stuff, we can't give it up now...
Sounds like my car. I have spent enough on keeping it running in the last year, I might as well pay for yet another repair.
I agree 100% with this. Every framework has its pain points - that is why it limits you as a framework, as opposed to homerolling your own solution.
The gain you get is better support for foundational tasks and the ability to focus on the high level business requirements faster. There are very smart people working on the teams of all of these frameworks, available for free with an MIT license and supported for free - take advantage of it, but don't expect any of them to be perfect and expect to still be putting in hard work in understanding the internals of all of them.
Dunno, most of the JS frameworks have crappy design and mediocre implementations. Angular is not some shining beacon, it's convoluted beyond belief.
Being a framework, and being from a large company doesn't mean much, nor it guarantees that the result reflects having been worked by "smart people".
The SUN people were smart too, and yet we got the J2EE shit-fest of early to mid 00's. IBM also shipped it's share of crappy frameworks, Microsoft too.
Also expect those framework based skills to be obsolete 4-5 years down the line, when some other shiny framework comes along.
Also expect to have to rewrite tons of your work, when the developers with ADD lose interest and go to rewrite the framework, like with Angular 2 (and I've relived these all over again with (Java) Struts 2, (Python) Zope 3, and tons of other stuff besides).
If all you got for bespoke and lean is a "20% speedup" then I don't think it's worth it.
You should be able to get at least 100-200% speedup...
They are only removing the V and replacing it with another V.