Angularjs expression size and watches

In Angular you can explicitly register a watch and a callback to be called when it changes
  e.g.
     $scope.$watch(expression, callback)
..or implicitly using a binding expression
 e.g.
    {{userName}}

Angular keeps track of all watches on scope so that it can detect when changes have occurred and thus update the DOM or call a watch callback.

Angulars code to detect changes by evaluating all the watches is called the "digest loop". The digest loop stores the value of the watch expression evaluation and when next the cycle runs it compares the old value to newly computed expression value. If there are differences then it will eventually intelligently update the dom and/or call impacted watch callbacks (once all changes have been resolved)

The awesome book "Mastering Web Application Development with AngularJS" explains this well in Chapter 11.
Chapter 11 includes a section on performance tuning. One advice is to "Consider the size of expressions being watched" i.e. the following bind expression will result in the whole paragraph being added to memory e.g.
<p>Changed. For more information about spreadsheet uploads see some interesting link to test watch size and if its a problem or not, just adding dummy text to test {{context.moreInfoUrl}} our help documentation.</p>

I tested this and measured in Batarang -> Performance tab -> Watch Expressions and can confirm that is indeed the case. Notice the first case below without an anchor tag the whole paragraph was added as the watch, whereas when the bind expression is wrapped in an anchor then only the bind expression is cached.

without anchor tag:
{"name":"Changed. For more information about spreadsheet uploads see some interesting link to test watch size and if its a problem or not, just adding dummy text to test {{context.moreInfoUrl}} our help documentation.","time":0.0209999998332933,"percent":"0.0891","$$hashKey":"02MSU"}

with anchor tag:
{"name":"{{context.moreInfoUrl}}","time":0.01999999221879992,"percent":"0.109","$$hashKey":"00IGY"}


So this is interesting and clearly has some impact on memory.
But for our app this is pretty uncommon. On the same page where the expression above was. there were lots of other watches ahead of either case in terms of time. Plus performance-wise there does not appear to be much difference between one and the other. So yes, good to avoid this and tune for it.

But we'll continue to dig into Chapter 11 and look to tune other things such as minimize watches, keep them slim and fast, avoid DOM watches etc. More to come on that.

Comments

Popular posts from this blog

deep dive into Material UI TextField built by mui

angular js protractor e2e cheatsheet

react-router v6.4+ loaders, actions, forms and more