Change - Know that nothing stays the same

AngularJS: Quick performance improvements

October 11, 2018

angularjs
performance

After a few talks about AngularJS and a companies looking for migrate systems to newest technologies or trying to improve current systems, anytime someone ask me:

What's the first thing you do on an angularjs app to improve performance?

A small and quick list to verify:

bidirectional binding vs one-time biding

Any element we put in a template using the expression syntax '{{ foo }}' it will create what is know as bidirectional binding for that element, this means that if anything on that element -the variables we use, the controller holding that variable, etc- changes foo value, it will show that change on our view.

This is what we want, but not always is completly true and sometime not necessary.

Not all our bindings will change after render it

We have many examples where we know our template wont change its content until we re-render the entire component, a quick exmple may be a component to show user data (show, but not change it). On this example we can use one-time binding with

{{ ::foo }}

the use of :: mark that expresion to not be watched for changes.

It's all about $digest

Every element we use as part of expression with the bidirectional binding syntax will be verified any time the $digest cycle runs, if the content of foo changes, it will renders the new value. When we have more elements doing this in our template, its more the cost of a $digest cycle. Usually devs refers to this elements as the numbers of watchers in a template.

If the expression will not change once set, it is a candidate for one-time binding.

Directives - a greate power with a grate responsability

Custom directives helps to do code for those special cases where we need to do something really specific and not common and any general code does not fit what we need.

Many of this custom directive will use $apply to trigger the $digest cylce to update whatever we need to update after some situation happen.

Is exactly here where we need to undertand we're triggering manually an verification/update on angular elements.

A good practice if we need to do this, is to only use this manual triggering on controlled situations and undertand the implcations on any other angular element we have rendered.

Expressions with functions

Is possible to use functions in angular expressions in our templates, for example if I have the following code:

template:

<p>{{$ctrl.orderSubTotal()}}</p>

model/controller:

function orderSubTotal() {
  return items.reduce(function(accumulator, currentValue) {
    return accumulator + currentValue;
  })
}

our expresion in our template will run the function on any $digest cycle, meaning a high cost if we abuse of this.

This is another example where we need to understand how we affect our app perfomance and when this is a necessary thing to do and when this is a high price to pay.


Agustin Vinao
Agustin Vinao.

Paradox: Life is a mystery. Don't waste time trying to figure it out.
Humor: Keep a sense of humor, especially about yourself. It is a strength beyond all measure.
Change: Know that nothing stays the same.