Vinc 웃
Vinc 웃

Reputation: 1247

Filter performance with ng-repeat with multiple ng-show inside

I have a ng-repeat with multiple ng-show condition inside. Something like this (fictive example):

<ul>
  <li ng-repeat="item in items | filter:searchFilter" >
    <label ng-show="item.label==1">{{item.label}}</label>
    <label ng-show="item.label==2">{{item.label}}</label>
    <label ng-show="item.label==3">{{item.label}}</label>
    <label ng-show="item.label==4">{{item.label}}</label>
    <label ng-show="item.label==5">{{item.label}}</label>
    <label ng-show="item.label==1">{{item.label}}</label>
    <label ng-show="item.label==2">{{item.label}}</label>
    <label ng-show="item.label==1">{{item.label}}</label>
  </li>
</ul>

I am using ng-show for formatting purpose, e.g. :

I want to show the cellphone column, when the item.cellphone is not empty...

I have a big data source (+1000 rows) and I have noticed performance problem when I use the filter.

If I remove most of the ng-show conditions, the performance is good. Here's live example :

  1. Ng-show performance problem
  2. Without ng-show

I know you can improve the performance with a "track by" (here's an topic about it), but it look like it is not enough to make the filter "smooth" (at least, not too laggy).

Is there a way to improve the filter performance of ng-repeat with multiple ng-show condition and a large data source ?

Upvotes: 0

Views: 1095

Answers (1)

DRobinson
DRobinson

Reputation: 4471

Performance tuning really depends on some of the constraints that you're facing. Here are a few suggestions:

1) Do you really need to show/hide the labels, or will not creating them at all suffice? If they don't need to exist, use ng-if instead of ng-show. This will reduce the number of watchers as well as the number of DOM elements in your example drastically.

2) If you can use Angular 1.3+ and can assume the labels are static ids, use one-time binding to avoid having so many watchers {{::label}}

Modifying your example with these suggestions results in: http://jsbin.com/madefuqami/2/edit

Ultimately, however, if you keep adding elements then at some point your app will become slow. Angular's dirty-checker will look at each of these ng-show (or ng-if) and {{}} bindings on every $digest cycle. Plus the DOM will get unnecessarily large - there's a good chance that you don't need the browser to do all of the work associated with maintaining HTML and styling for element 3000 when only 1-50 fit on your screen.

A more robust solution would involve looking into pagination or virtualization. This can either be done server-side, or in Javascript.

I suggest server-side pagination. Ultimately, it will scale better and make for a cleaner solution. However, if you decide to go the Javascript virtualization route, there are libraries available already such as angular-virtual-scroll

Upvotes: 3

Related Questions