简体   繁体   中英

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, eg :

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 ?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM