
AngularJS Performance in Large Applications - arnauddri
https://www.airpair.com/angularjs/posts/angularjs-performance-large-applications
======
DigitalSea
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.

~~~
fngegngkg
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!

~~~
DigitalSea
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.

~~~
coldtea
> _Not everyone has the luxury of throwing away one years worth of work and
> choosing something else._

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...

~~~
collyw
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.

------
rattray
By comparison, it seems that the equivalent article for a React application
would be "use immutables and PureRenderMixin", full stop.

I've been developing with React for the past several months and the idea of
going back to Angular is already painful.

I've been looking for opinions on why Angular would be preferable to React. I
haven't found any; can anyone else who's used both comment?

------
gedrap
Nit-pick, but I don't agree with his definitions of complexity.

>>> The second reason software is slow is known as space complexity. This is a
measure of how much 'space' or memory a computer needs to run your solution.
The more memory required, the slower the solution.

Requiring more memory doesn't make an application slower by default. It simply
means it requires more memory to run as expected.

Similarly, when he's talking about run time complexity, he calls it "a measure
of how many comparisons a program needs to make to achieve a result". It can
be any action, not necessarily a comparison. Be it number of times cycle needs
to be executed, number of expensive calls to external service, etc. Number of
comparisons to make is commonly used in introductory courses when studying
sorting algorithm but doesn't make much sense without a context.

~~~
oinksoft
Also disagree with

    
    
      > 6.2 Watching Functions
      >
      > Another common problem is the utilization of functions
      > in watchers or bindings. Never bind anything (ng-show,
      > ng-repeat, etc.) directly to a function. Never watch
      > a function result directly. This function will run on
      > every digest cycle, possibly slowing your application
      > to a crawl. 
    

A while ago this sort of advice was true (when you'd see people inlining stuff
in `eval` to avoid this), but nowadays function execution itself is very fast.

You don't want to watch a slow function, but just watching a function will not
"[slow] your application to a crawl."

Interesting post, but I'd take this author's advice with some salt.

~~~
teen
I disagree strongly as well. For example if you have something like ng-
show="is_admin()" and $scope.is_admin = function() { return $scope.logged_in
&& $scope.role='admin' } or some other complexity reducing function, I don't
understand how that would be significantly less performant than copying and
pasting the return statement everywhere in your html.

------
progx
Can somebody explain me what "large Applications" are?

I read it many times, but when i compare it to the "little" Tools i write for
my company, it seems that this "large" Applications are really really tiny.

So what did you understand under large Applications?

~~~
lightblade
Large should be at least 80k lines of code, preferably more than 100k.

Another metric I go by is there is no one on team have overlapping knowledge
of the code base. In other words, no other teammate is suited to review your
code because they have no context of it.

~~~
nostrademons
By the second metric, Google is not a "large" software system because all code
must be reviewed by someone with context on it. (Single-developer projects and
codebases don't get anywhere at Google...I tried, multiple times.)

I think a decent definition is "software where no one person has the whole
system in her head", i.e. where reading existing code takes as least as much
time as writing code, and any change may have unforeseen ramifications on the
system as a whole.

~~~
twrkit
> Single-developer projects and codebases don't get anywhere at Google.

As a Googler working on a single-developer project / codebase, I'm sorry to
hear that you didn't get traction. Very grateful for my mostly autonomous role
:) There are tradeoffs of course, but to me the reduced overhead of no
meetings and greater creative control are worth the trouble of an increased
workload and providing support.

~~~
nostrademons
Good luck. I really loved the experience as well, it's just that the project
got canceled when my management sponsor moved to a different department and
his replacement was like "No more one-off projects." The funny thing is - I'd
been warned by some very senior and very accomplished (outside of Google)
people that independent projects basically never launch, but since my manager
was very supportive, I'd discounted the warnings.

------
thruflo
A couple of times, the article mentions using:

> services and object references to propagate object changes between scopes.

There are so many ways to wire things up in Angular -- references, watches,
broadcast/emit -- that I'd love to see some examples from the author, who
seems to really know what he's doing.

For example, say I have a `userService` that maintains a small `user` model
with username, name and roles properties. What's the most performant and
maintainable way of "binding" to changes to this object so when I call, e.g.:
`userService.logout()` somewhere, some component I write can pickup the change
and adjust it's state / UI accordingly?

~~~
fein
I think the only way to do what you want with your service is by injecting
rootScope and using $emit, since we're trying to capture a "logout" event and
tell our other controllers about it.

Reacting to the specific event would likely waste less resources than pulling
out the $watch or $watchCollection sledgehammer.

------
thoman23
If you aren't going to use $scope.$watch, you might want to ask why you're
using Angular in the first place. From my own experience building a large-ish
hybrid mobile app in Angular, I haven't run into any performance issues. While
you should of course understand the implications of how you structure your
application, I would also warn against premature optimization. I advise
building first for simplicity and ease of maintenance and then tweak for
performance if needed.

------
nikon
Common things I have encountered:

$scope.$watch()ing large arrays unnecessarily will be the death of you

Using ng-show where there is complex render logic in that element, consider
ng-ifs to remove from DOM completely

Using track by in ng-repeats can help

We had simple screens which would hide any symptoms of bad practices but once
you have an 'overview' screen with 10 different lists, many different
show/hide forms etc the page can get slow very quickly.

------
serve_yay
There is some good info here. But when your Angular app slows to a crawl, it
won't be because you used objects instead of arrays.

------
uptown
What's the current best guide for learning AngularJS? Is angularjs.org my best
bet, or would you recommend some other resource?

~~~
squeaky-clean
I've been using this SO answer[0] as a list of good resources. The egghead.io
videos have been most helpful to me, I really enjoy the "bite-sized" videos
style and the way the speaker explains how attributes/vars relate to others in
the application. Here's their specific page for beginning AngularJS.[1]

[0] [https://stackoverflow.com/questions/14333857/how-to-
master-a...](https://stackoverflow.com/questions/14333857/how-to-master-
angularjs)

[1] [https://egghead.io/articles/new-to-angularjs-start-
learning-...](https://egghead.io/articles/new-to-angularjs-start-learning-
here)

------
vegancap
"application error" ...is this site written in angularjs? If so I think we
have the answer to that title! :)

~~~
hhsnopek
haha if it can't host a simple blog.... then can it really scale?? ;)

~~~
vegancap
I'm praying for this blog to be Wordpress as I've just started a project in
angular!!

~~~
gedrap
Angular performance has nothing to do with handling a lot of traffic.

~~~
vegancap
It was a joke...

------
aturek
If anyone, like me, didn't know about 'track by' as a way to optimize ng-
repeats, here's a couple of articles that explain what it is and why it's
beneficial:

[http://www.codelord.net/2014/04/15/improving-ng-repeat-
perfo...](http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-
with-track-by/)

[http://www.bennadel.com/blog/2556-using-track-by-with-
ngrepe...](http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-
angularjs-1-2.htm)

------
JDDunn9
9.4 seems to be an outdated issue. Since version 1.2.16, $rootScope.$broadcast
does not go to all child scopes, only those with a watcher. It's very fast,
and perfectly fine to use if you need it.

------
exratione
This is still fairly applicable for the major causes of speed and slowness.

[https://www.exratione.com/2013/12/considering-speed-and-
slow...](https://www.exratione.com/2013/12/considering-speed-and-slowness-in-
angularjs/)

My impression is that Angular-specific issues are way more important than pure
Javascript speed concerns in terms of relative impact on an application.
Number of watchers and ng-repeat declarations are the most important aspect of
an AngularJS application.

------
dmak
I disagree with 9.4 as I think you should try to use event emitting more. This
is the best way to modularize your application and really separate your
concerns.

For example, given a service in charge of dealing with the a part of user's
data. All mutations should be done through the helpers given by the service
and then it should emit an event telling everyone subscribed to deal with it
and update themselves.

Doing it this way, you maintain much more sanity when you have to create a
really reactive application.

~~~
rattray
Interestingly, this is essentially the React/Flux model in a nutshell.

------
s_baby
>Similarly, Angular provides the ability to watch entire objects by passing a
third, optional true parameter to scope.$watch. This is, for lack of better
words, a terrible idea. A much better solution is to rely on services and
object references to propagate object changes between scopes.

How am I supposed to then propagate these changes into the DOM if I'm not
using $watch?

------
mackraken
uh... re Loops: "Try and avoid making calls in a loop." This is an over
simplification. The author draws the wrong conclusion from the example given:

    
    
        for(var x = 0; x < 100; x++){
          var keys = Object.keys(obj); 
          sum = sum + keys[x]; 
        }
    

The problem here is needlessly invoking the same operation 100 times
(Object.keys).

~~~
collyw
I assume he was just explaining it badly.

------
CSDude
Seems it is down, Google Cache:
[http://webcache.googleusercontent.com/search?q=cache:www.air...](http://webcache.googleusercontent.com/search?q=cache:www.airpair.com/angularjs/posts/angularjs-
performance-large-applications)

------
jdawg77
Large and small are fuzzy metrics. A subset of non binary thinking (see Kosko,
the model of probability and the hypercube, etc). "Jeremy is short," well - to
a 5'0 person, I'm freaking tall.

To Yao Ming, I'm short. Trouble is, we each of us technologists tend towards
introversion (been struggling since...well, take my age and then subtract
however many years my communication skills were less than stellar).

Ever try to raise money for an idea based on numbers? It's like trying to land
a date based on the size of your...real estate. Sooner or later, another yutz
shows up, plops _his_ drink on the counter and announces that the yacht he
just stepped off was twice the size of yours.

Ya, it's never a fun game because it necessitates that binary outcome. Suffice
to say good tools in the wrong hands can still be used to chop off your own
feet if you don't pay attention.

