Loading 24k entries into a select list efficiently - javascript

I have a classic ASP page that when loaded does a JavaScript call to another ASP page to retrieve XML to load into my <select> box. It has to load roughly 24k options; needless to say, this is rather cumbersome.
They don't all need to be loaded in immediately and it doesn't matter if it actually takes a while to load as long the page doesn't hang. The page needs to work in IE6+ (bummer).
I've considered that when a user scrolls past a given section it will load in 100 more, however, can't find an appropriate property that will work in IE6 for scrollbar position. I considered using onmouseover of a specific option (i.e. "Hover for more results...") but the event doesn't fire.
If anyone can point me in the right direction I'd really appreciate it. :>

You should set up a service that lazy loads your items into the Select List using something like a server side backed store.
If I were to try and tackle this problem, I would go down the JsonRestStore route and using the Dojo Toolkit, to request items as they are needed, then populate them into a ComboBox/FilteringSelect.
Here are some resources for you.
http://livedocs.dojotoolkit.org/dojox/data/JsonRestStore
And here is a demo of what Filtering Select can do.
Just as a final note, I might add, that loading all of these into the DOM, will always be a bad idea. You should use a grid or something, or use a predicter as they type to narrow down.
I use a JsonRestStore which powers a grid with around 5 million items. All I do is load new items as the user scrolls down the page. As they scroll, it detects that I need to pull another 25 items from the server, this kicks off a new query, and then it gets loaded into the grid.

By "select list" I presume you mean the HTML element
<select>
<option>option 1</option>
...
<option>option 24000</option>
</select>
In short, more than 10-15 options in a select list is REALLY BAD USABILITY. So if this is your case you may want to rethink the interaction, since even rocket scientists will have a hard time finding and selecting just the right option out of 24000 options.

To anyone absolutely stuck doing this with a dropdown box the only way I could get it to not lock up the browser was using setTimeouts. In chrome this runs perfectly fine, but the lowest timeout IE can accept is something like 13MS and really hampers load times. On top of that I (personally) think it's a pretty ugly solution... but it's better than locking up the form, I guess.
var i = 0;
function doStuff()
{
// code to execute, ie, add items
i++;
if (i != end of loop)
{
setTimeout(doStuff, 1);
}
setTimeout(doStuff, 1);
Another piece of advice I found was to avoid reflows by using a code fragment or hiding the dropdown box (simply setting style.display to "none") until all the items are added.

Related

Modal dialog with dropdown list is not fading out right away after dismissal

I've got an angular app and I integrated it with UI Bootstrap project. I'm using regular
The modal dialog with dropdown containing 750 records, when one of the items is selected and clicked "Ok" or "Cancel", the modal and the overlay fades out without any delay.
Here's the plunker:Modal dialog with 750 records
If the modal dialog with dropdown containing around 10k+ records, and one of the items is selected from the list. Clicking "Ok" or "Cancel" is not hiding the modal dialog right away, instead I'm having a 8-10 second delay on Chrome, I've not tested on IE yet.
Here's the plunker:Modal dialog with 10k+ records
Question: Why I'm having performance hit with more data?
You are slowing the whole entire browser down by grabbing the DOM by the neck and pouring 10,000 <option> nodes down its throat. You need to lazy load your data somehow. Ever noticed on sites like Twitter, Facebook, and others that when you scroll to the bottom of the page it will begin loading more records from the server? Good apps will start to garbage collect old records that have been scrolled up as well.
When you scroll through your Facebook news feed it's not loading all your friends post since 2007 into the browser all at the same time. Once a maximum number of posts exists in the DOM Facebook will start removing the oldest ones you scrolled up to make room for more and grab fresh posts from the server so you can continue scrolling. You can even see your browser scroll bar jump up as you scroll down because more posts are being added to the DOM.
No browser is going to be able to handle that much data. The browser is not a database. I'm amazed your plunker with 10k records is as performant as it is! Haha. A dropdown is not what you want to display that data. You're going to have to sit down and think of a better way to show that data to the user. My first thought is to provide a filterable list that initially contains the top 25 most selected options or something, then typing in a search field causes it to load a new list from the server that matches the search criteria. Only you will know what your users will actually want, but I assure you it's not a dropdown list with 10k+ options.
Example:
Notice how the browser scroll bar jumps up a bit when it gets to the bottom. Twitter gets to the bottom and then loads more data to scroll through. It will eventually start cleaning up data at the top of the page as well if I scroll far enough.
Modern browsers can handle a lot, but 10,000+ <option> nodes is pushing it overboard.
The browser can handle a large number of values in a dropdown list, but a dropdown list isn't meant for such a task. Not to mention the users will have a hard time selecting an appropriate value, even if you sort them alphabetically.
You would be much better off using an input text box instead of a dropdown.
jQueryUI has some nice autocomplete features that would improve not only the performance of your web application, but also make the user experience much more bearable. I would any day prefer to type out one of the 10,000 options provided to me than search for them in a dropdown using a mouse and select them.
Here's an example on jsfiddle with ~8.5k records for a performance test.
Let me quickly tell you few points:
It is a usability bug to scroll through 10K records. Consider someone going through 10K options and selecting the one which they want. Not a good idea.
Performance issue:
If the options were rendered from a back-end in a traditional way (non-Angular way) then it would just take time to load but after that the performance won't be such an issue.
Since, you are using AngularJS with ng-options, the options are populated in the front-end and you have all the data in Angular's scope. To perform, two-way binding, Angular always does a dirty-checking in each 'digest cycle' which loops through each and every data element in $scope and causes that delay.
Solution:
Use Select2's "Loading Remote Data". Select2 is a jQuery based replacement for select boxes.
Consider using the AngularUI's Select2 wrapper instead of directly using it.

Efficiently rendering a large number of "select" elements

I'm writing a web application that displays a large number of rows of data (~2000 at present), each of which has a drop-down "select" element with ~100 options. Any of those options can be selected by default. I'm generating all the actual DOM elements client-side. My problem: rendering this beast takes ~4 seconds on my relatively recent machine, which is really suboptimal. I know the problem is specifically with all the select elements, because replacing them with a bit of static text or a single-option list causes render time to be nigh imperceptible.
The vanilla code, minus failed experiments (see below) is here.
Avoiding the suggestions of "paginate your data" and "don't have so many options in a select", what is the most efficient way I can write my append / render code, assuming I do have a legitimate reason to display that much data and have that many options? For my purposes, Firefox is the only platform I care about.
Things I have tried:
Using an async loop to append rows to the table (slower than a regular loop, and oddly didn't render the intermediate results)
Building up a string that represents the body of the table and inserting it into the DOM in a single call (almost identical performance)
Instead of inserting the entire options list, inserting a single-option "select" element, and then populating the entire list when the "select" element gains focus (presumably because someone is trying to change it). This was actually pretty high-performing for the initial render, but then populating the element with the full list caused some weird behavior, losing focus and never actually being able to "open" the select element.
Right now my default assumption is that the third option is the way to go, and I need to figure out how to do some bookkeeping about what has already been populated. But my suspicion is that there is a plainly better / faster / more idiomatic way to do this. Is there?
Yes, I would "lazily" generate and/or populate the dropdowns.
That is, only create and populate the dropdowns when the user clicks on them, as probably almost all of the dropdowns in the 2000 rows will never be used right?
Perhaps a select element might not be the best UI here too, but instead some kind of HTML menu like so: https://jqueryui.com/menu/ that is created, populated and displayed only when the user clicks on some kind of button to display it.

living web page elements

I have a simple rails app with a model Task, which has 10 rows. It does not matter what's inside this table. On the index page I can see all 10 elements and I need to arrange them in proper sequence, when I did this, I should see a message "Done".
If I understand correctly this should be implemented in javascript, because page should not be reloaded, right?
I want to be able to rearrange the elements via drag and drop.
How I can realize that function?
I would start with here -> http://jqueryui.com/demos/sortable/
You can sort and its quite simple as there great examples on the site how to do this and hook into events.

Refreshing "online" users with JavaScript

I have a chat app where it shows users who are online (username + profile pic). I have an ajax poll that basically checks to see which users are still online, and refreshes the list automatically. Also, the list is ordered based on last activity.
The way I've been doing it is:
Get list of current online users
Clear existing elements
Re-add them (will be ordered correctly since the returned list from step1 is ordered)
This works fine in Chrome, but I notice in Firefox that it is causing a "flickering" effect while the images get re-added.
What is the best way to do this? It seems overly difficult to create an algorithm check which elements exist, if they are in the right order and move them, etc. Thoughts?
How often do you poll to see if users are still online?
I think the best way may be to give the user records unique ids so you can then check the list of users that were online against the new list of users that are now online.
fade away the users that have left and fade in any that have logged on.
It will be a much more elegant solution and it solves the problem you are having.
Firstly, I would try to "cache" the images separately, using the "preload" technique. That's when you create an Image object and set it's src to the URL of the userpic. Then you store all those objects in a global array. This will prevent the browser from getting rid of the images when they are no longer on the screen, so that it will not have to load them again when you reload the list.
If that doesn't help, I would actually reuse the existing list elements. I would just go over the elements, one by one, and replace their content with the appropriate content from the list. If I run out of existing elements in the process, I add new ones. If any elements are left over when the list ends, I remove them. This is a bit more complex, but actually not as complex as it looks at first glance.

Combo box behaviour in IE7

Hi I know its not a good idea but due to one use case I am populating a combo box with more 10000 items. Its behaving very weired in IE7 in all other browsers its working fine in IE7 its taking too much time for downloading the page. Sometime IE7 also hangs up
Is there any known bug with IE7 for this issue.
Thanks,
Amit
Not sure whether anything can be done to speed this up. One thing to look into would be loading the options dynamically through Ajax, and adding them as DOM nodes to the existing select element. That would at least allow the whole page to load before the rest of the data is fetched.
There are ready-made JS/jQuery-based Ajax combo boxes as well. One with a good loading strategy might yield better results.
I have no experience with them so I can't tell which one is suitable for you, but these seem worth checking out:
DHTMLXCombo (not free)
More in this question
I would suggest abandoning any attempt at having 10k entries in a single select box -- as others have said, it's a user interface nightmare, even if you can solve the problem with it killing the browser (which I don't think you can).
What to do instead?
Break the selection into categories. Then have one <select> box for the category, and have a second <select> get populated according to the category that is picked. This second <select> could be populated via Ajax or a page reload; both techniques are common. Given the quantity of options you want to provide, you may even want to break it down into category and sub-category.
The other alternative (which may be better, given the number of options you're providing) is to implement a Google-style auto-complete. There are a number of easy-to-use Javascript and JQuery scripts out there which allow you to implement this sort of thing without having to write it from scratch - it's almost as easy as writing the select box.
Here's one for you to try: http://docs.jquery.com/Plugins/autocomplete (but there are plenty of others if you google)
Hope that helps.

Categories