Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
276 views
in Technique[技术] by (71.8m points)

AngularJS 'ng-filter' is very slow on array of ~1000 elements

I have a simple <input> search filter set up for a list of itemnames in AngularJS.

My list looks like this:

var uniqueLists = {
    category1: ['item1', 'item2', 'item3' ... 'item180' ], // Real list contains ~180 items
    category2: ['itemA', 'itemB', 'itemC' ... 'itemZZZ' ], // Real list contains ~1080 items
    category3: ['otheritem1', 'otheritem2', 'otheritem3' ]  // Real list contains 6 items
  }

I iterate through this list in Angular and print out the results in a <ul> for each category.

<div ng-repeat="(key,val) in uniqueLists">
    <form ng-model="uniqueLists[index][0]">
        <input ng-model="searchFilter" type="text" />
            <ul>
                <li ng-repeat="value in val | filter: searchFilter">
                    <label>
                         <input type="checkbox" ng-model="selectedData[key][value]" />
                        {{value}}
                    </label>
                </li>
            </ul>
    </form>
</div>

For clarity, selectedData looks like this:

var selectedData = {category1: [item1:true], category2: [], category3: []); // if 'item1's checkbox is checked.

This list is working just fine, although the filter is quite laggy, even on my quite-fast computer. Typing a letter into the input takes 1-2 seconds for the list to update.

I'm aware that this is likely because I'm filtering through around about 1000 items at a time, but I haven't seen any discussion of this elsewhere.

Is there any way to get better performance out of the filter?

question from:https://stackoverflow.com/questions/17969207/angularjs-ng-filter-is-very-slow-on-array-of-1000-elements

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The main problem with the filter approach is that upon each change the dom is manipulated, so it's not the filter that's slow but the consequences. An alternative is to use something like:

ng-show="([item] | filter:searchFilter).length > 0"

on the repeated element.

Lending some code from @OverZealous, you can use the following to compare the behaviour:


Update: With Angular v1.2 came the track by syntax. Which also helps with such problems. Provided the elements have some unique attribute, one can use:

ng-repeat="item in items | filter:searchFilter track by item.id"

Where item.id has to be unique across all items. With track by only those dom-elements will be removed which are no longer the in the final list, others will be remembered. Whereas without track by the whole list is redrawn everytime. In short: much less dom manipulation = quicker redraw.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...