-
Notifications
You must be signed in to change notification settings - Fork 1.8k
big array performance issue #389
Comments
You could virtualize the list, only rendering DOM that are in view. |
@amcdnl can you expand your idea? Now my script for counting watchers on the page is showing 3163 watchers (2 fields with ui-select and list of countries) so too too much. UPDATE: I've reduced by 2000 watchers after remove datepicker from angular-ui packet. |
I could use an answer for this. I'm not sure how to proceed with a list of 14k in my dropdown. I wanted to use minLength but that's not implemented yet. |
@simkessy I've implemented min length in my project, and limit with result, you can check related issue : #274 (comment) where I wrote solution for this. Here you can check how I resolved limit for result : https://gist.github.com/masscrx/3a9ba4b3df4cdd7012ea and in html you can add something like this then:
This is my workaround for big array till guys make some official functions for this ;-) |
@masscrx sorry for the delay, busy week. Virtualizing a list means only the viewable items are rendered in the dom. The other items may be in memory or paged at the server level when came into view. Heres an example ( would not recommend trying with our select though ) but gives the idea: https://github.com/kamilkp/angular-vs-repeat |
Tagging as an enhancement; PR's welcome if you want to contribute. |
this would be huge. I would not mind working on it at some point but that would require me to not be busy... so not any time soon I think |
+1 |
What about virtual dom like react type implementation? |
Interesting that might do the trick. With a react style dom we could have On a related note I did notice we have a lot of slowdowns that just come |
I also noticed ng-if slows ui-select down when it gets opened, but after quick profiling I found that it's because of ngAnimate, that by default "animates" every ng-if, ng-show, etc. (a lot of requestAnimationFrame calls). When I turned-off ngAnimate for ui-select it became 2x faster. But this is only if you use ngAnimate, of course. |
If this PR #430 could get merged in it would probably solve a lot of the issues as well by limiting the DOM size. |
Any word on virtualizing? This is something that's come up for us as well. |
I have not done anything with it. infinite scrolling may still be the best bet and if not that then #430 |
@Anton-Rodionov How did you turn off ngAnimate on the ui-select. I, too, am getting rAF calls for every item in the list, which slows it down considerably. |
Also interested in turning off ngAnimate effect on the ui-select component, while keeping it working for other components. |
+1 |
You guys might find some inspiration from here; select2/select2#781 — since Select2 guys were having similar problems. |
+1 |
1 similar comment
+1 |
I have had recent success with infinite scroll using this library. http://binarymuse.github.io/ngInfiniteScroll/ it is a bit more work, but if you only have a few big lists then this is decent work around. |
@dmccown1500 could you post a demo of what you did? |
Hey sorry did not have a ton of time, but I threw together a plunker. It is not quite working right (no idea why seems like the same thing I did on our webapp) but should at least give you some direction: http://plnkr.co/edit/OwhFCyHz0mO1yZMj5UW5?p=preview |
Update ok I got it working now: http://plnkr.co/edit/OwhFCyHz0mO1yZMj5UW5?p=preview I realized we were using a modified version of the library. pretty small change but it was slightly different. All credit to the ng-infinite-scroll team for the bulk of the code |
@dmccown1500 thank you!! your plunker is very helpful :) |
@twrk glad to hear is was helpful. I love this library and would really like to see something like this get pulled in natively. |
@dmccown1500 thank you too!! it's magic! |
Yeah I saw it here, but I didn't see an option to disable tagging. I have a list of airports and the user must select one of them, not create a new one. Edit: I'll take a look later today. That could work for me. |
+1 |
Did anyone ever solve this? I have a list of 700 items and I'm getting complaints about performance with no clue how to go about solving this. |
@dmccown1500 is there a way to use virtual repeat from ngmaterial with ui-select to fix the performance issues |
@simkessy I never tried I moved to a different project where the library was not in use so it kind of fell off my radar. Seems like it might work? |
I just moved from oi-select to ui-select because oi-select doesn't support using scope variables to populate its attributes for some reason. Took me a good 3-4 hours to re-theme from oi to ui and rewrite some code. And now this... gah! |
@AdamGerthel, this isn't a fix exactly, but I was able to help my performance by introducing a min-length and using the refresh directives built in. Essentially, I would only populate the dropdown when the user entered at least 2-3 characters. Pros: Significant performance improvement, instead of rendering 700 items I'm only showing a subset |
@simkessy thank you! It worked wonders. I followed this approach: #88 (comment) |
@dmccown1500 thanks for providing your solution with infinite scroll! Very cool stuff :) Unfortunately it doesn't seem to be working with the latest version of ngInfiniteScroll as it attaches by default to the window and not the container. I tried using the exact copy of infinite-scroll you used in your plunkr demo and noticed that ui-select would redraw itself after increasing the limit dynamically, thus each time you scroll and it adds more items it skips back to the top of the list again. were you able to get your solution to work with the latest versions of infinite scroll and ui-select (ie. 0.14.x or 0.16.0) ? |
@stringbeans I left the project where I was using ui-select so I have not kept that up to date. So if you need a feature from one of the newer versions then you are kind of out of luck. Sorry! |
Is there any fix on this issue? |
@TravisTam feel free to submit any PRs you feel could improve performance. I'll be happy to review 😃 |
Hi, wanted to share what I did in my project.. First commented the same line that mentioned @facesea: But also the major problem with ui-select is using it with Then, if you don't use filter in view, Finally I had to modify select.js to emit an "on-filter" event when
Hope this tips helps to improve the library. |
@stringbeans you're right, the latest infinite scroll plugin uses the window by default, but it does allow you to modify the container. The scope properties are: {
infiniteScroll: '&',
infiniteScrollContainer: '=',
infiniteScrollDistance: '=',
infiniteScrollDisabled: '=',
infiniteScrollUseDocumentBottom: '=',
infiniteScrollListenForEvent: '@'
} However... I've tried in vain to set it up to work correctly. You need to pass a selector to |
any news on this issue? |
@jocluz this issue is up to date with all info posted so far, what further news do you require? Feel free to submit any PRs you feel could improve performance I'll be happy to review 😃 |
I also have found a solution similar to some above, but in to my eyes was a bit more straight forward. In the view <ui-select-choices repeat="school in filterSchools($select.search)">
<div ng-bind-html="school.name | highlight: $select.search"></div>
</ui-select-choices> In the controller. I have a list of 3,000+ schools, and I have no need for the user to scroll through them all at once so I return an empty array when there is no search term. When there is a search term I limit the array to 30 items. $scope.filterSchools = (search) ->
return [] if !search
limit = 30
index = 0
searchRegex = new RegExp(search, 'gi') # gi = global and case insensitive
return $scope.schools.filter (school) ->
if school.name.match(searchRegex) && index < limit
index += 1
return true If you want the dropdown to look nice (invisible) when there are no items in the array then you might want to edit the css of |
@evenicoulddoit I'm also having a hard time integring ng-infinite-scroll. I've tried to add infinite scroll attributes to ui-select-choices like:
No success so far - probably because the container to which I'm pointing is not really a parent of ui-select-choices but it's the element to be scrolled itself. |
@benwigley I tried something similar to you, but in my case I have 100k records in a list... The dropdown gets populated really fast and it seems to work. I'm using a multiple select and when I select more than one object it transform all the objects to the one selected last... I think the binding can't work in my case but if I bind to the full list the performances are terrible. Not sure what to do. |
@Remiz if you want to stick to ui-select, hooking up infinite scroll seems like the only option imho. |
Infinite scroll solution is misleading. the problem still persists, if you keep scrolling down the performance will start to degrade again as the list grows and grows. You can use LimitTo and Begin with dynamic variables that change when you hit ScrollTop and when you scroll to the bottom. But now I have a problem where the search only operates on what is in the list (restricted by the LimitTo) and not on the complete array. Is there a way to get it to search the underlying array instead? Any advice appreciated, I'm very close to having a solution to this problem! |
IMHO, root of the problem is in intensive and undjustify use of forced digesting. Also I'd say that ngModel is used rather strange way. I didn't find a single $commitViewValue in the code. |
@sshalayev it's a real shame you couldn't contribute your changes back to us here, I'm sure a lot of people would have been grateful if you did. Consider submitting them in smaller chunks if you want, it will save you having to constantly keep your own fork up to date after all! 😁 |
Adding comments here since I'm also interested in a way to speed up performance, 200 rows already is a killer. |
@cristianocoelho @user378230 Checkout this one for a working version: #88 (comment) |
We've also been having some performance issues with In addition, there is a way to make the change on a per-instance basis and without forking the repository or keeping a locally modified copy of the library. We created a directive that requires
and use as follows:
|
Hi,
I have form for customer information, with three fields which use ui-select, every is for selecting country (country array length is 251) when countries array is loaded for ui-select it causes some lag on the page with this data, I've saw that there are some issues open with pagination for far future so now I can resolve my problem by adding checking for minimum input length for example 3 characters, than pagination is made on backend, but when customer is loaded with such information like $scope.customer.country_id I need to load all countries before, so solution with minium input length for 3 characters can't be applied in that case. Some ideas how to achieve that? I was trying to reduce watchers by adding :: to ui-select's expressions (one time binding - Angular 1.3 feauture) but with no result.
The text was updated successfully, but these errors were encountered: