close

  menu      DavidRodenas
CONTACT  
Main article: Contributions »

Angular1 Performance: ngClass inside ngRepeat

October 14, 2016

I present a little trick that improves digest loop performance 10 times in our applications. It is very useful when we use ngClass directives inside ngRepeat.

Tags: contributions


<td ng-class="{completed: todo.completed}">...</td>
<td ng-class="todo.completed && 'completed'">...</td>

ngClass notations

In this post I consider two kinds of ngClass notations: object notation, and string notation.

Object notation

<td ng-class="{completed: todo.completed}">...</td>

ngClass receives an object in which each key is a css class and its value is a boolean condition, if this condition is truthy ngClass adds the css class to the element, and if it is falsy ngClass removes it.

Object notation is the most common notation widely accepted.

String notation

<td ng-class="todo.completed && 'completed'">...</td>

ngClass receives a string or a false value. If the expression evaluates to a string ngClass adds the resultant css class. If the expression evaluates false ngClass does nothing or removes the css class added.

String notation is rarely used and it looks like a hack.

How string notation works?

Javascript && operator semantics is the following:

Expression Result
truthy && ANY ANY
falsy && ANY falsy

Given the previous example replacing truthy/falsy by todo.completed and ANY by 'completed' we get:

todo.completed && ‘completed’ condition && ‘completed’
false && ‘completed’ false
true && ‘completed’ ‘completed’

Thus ngClass using string notation receives either a false or a 'completed' string.

Comparison

Readability and maintainability

Object notation is simple to understand: in one side you have the css class name and in the other the condition. You can add or remove properties to the object easily.

String notation is more complex: you need to understand javascript boolean evaluation insights. If you need to specify only one class is easily readable for those who know this notation, but if you need more than one css class it becomes really complex.

Performance

Digest-loop times of both notations are:

  Object notation String notation
Few ngClass 0.07ms 0.02ms
Thousands ngClass 12.50ms 0.75ms

Object notation is expensive: ngClass has to compare objects to know if there are css class to add or remove.

String notation is faster: ngClass just need to process a plain value, either a string or a false.

Conclusion

If you have few ngClass directives use object notation. It is easier to read, to understand and to maintain. Digest-loop times under 1ms are negligible.

If you have hundreds or thousands ngClass directives active at the same time you should use string notation. Having a digest loop larger than 8ms are not recommended because the user start to feel the application sluggish. Using string notation is easy to keep digest-loop times under 1ms.

Replicate benchmarks

Performance times are obtained using benchpress.

You can replicate the experiments with the benchpress benchmark inside AngularJS git repo ng-class-bp .

More information

  • Digest loop: https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest
  • Benchmark pull request: https://github.com/angular/angular.js/pull/15243

« Back to List