ComboBox: filter very slow

19 posts, 0 answers
  1. Drew
    Drew avatar
    22 posts
    Member since:
    Mar 2009

    Posted 28 May 2009 Link to this post

    i have a ComboBox control that has dynamic items which are loaded on the initial page load. there is a significant lag between the time the end-user begins typing and when the filtered items show up. the maximum items will never be more than 1000 and each item can be up to a 100 characters long. another thing is this control is contained within a .ascx control that will be used in multiple places. is this just a browser limitation? i'm assuming it has something to do with it because when i run it in chrome it is blazing fast.

    Drew
  2. Raul Veloza
    Raul Veloza avatar
    1 posts
    Member since:
    Feb 2010

    Posted 08 Mar 2010 Link to this post

    I have the same problem With a Filtered ComboBox, But I have more than 2000 items on it. Can some one show a perfomance improvement so we can fix this? Thnx.
  3. Steve
    Steve avatar
    1885 posts
    Member since:
    Dec 2008

    Posted 08 Mar 2010 Link to this post

    How are you populating it, serverside dynamic or webservice?  Can you post the code?
  4. Drew
    Drew avatar
    22 posts
    Member since:
    Mar 2009

    Posted 08 Mar 2010 Link to this post

    hmmm, it almost took 1 year for some kind of response on this thread....

    i am populating it server-side, on the initial page load. here is my code:


    private void PopulateComboBox(List<Field> fieldList) 
        List<Field> fields = new List<Field>(fieldList); 
        fields.Sort(new FieldCollection.SortByOrderComparer()); 
     
        comboBox.Items.Clear(); 
        comboBox.EmptyMessage = "Search..."
     
        List<Field> systemFields = fields.FindAll(delegate(Field f) { return (f.Domain & FieldDomain.AnySystem) > 0; }); 
        if (systemFields.Count > 0) 
        { 
            RadComboBoxItem i = new RadComboBoxItem(); 
            i.Text = "System Fields"
            i.Value = String.Empty; 
            i.CssClass = "comboitem fieldtype"
            i.Enabled = false
            comboBox.Items.Add(i); 
        } 
        foreach (Field f in systemFields) 
        { 
            RadComboBoxItem i = new RadComboBoxItem(); 
            i.Text = ((IListItem)f).Text; 
            i.Value = ((IListItem)f).Value; 
            i.CssClass = "comboitem system"
            comboBox.Items.Add(i); 
        } 
     
        List<Field> customFields = fields.FindAll(delegate(Field f) { return f.Domain == FieldDomain.Custom; }); 
        FieldGroup lastGroup = null
        FieldGroup lastSection = null
        if (customFields.Count > 0) 
        { 
            RadComboBoxItem i = new RadComboBoxItem(); 
            i.Text = "Custom Fields"
            i.Value = String.Empty; 
            i.CssClass = "comboitem fieldtype"
            i.Enabled = false
            comboBox.Items.Add(i); 
        } 
        foreach (Field f in customFields) 
        { 
            CustomField cf = (CustomField)f; 
            FieldGroup section = (cf.Group.Parent == null ? null : cf.Group); 
            FieldGroup group = (cf.Group.Parent == null ? cf.Group : cf.Group.Parent); 
            if (group != lastGroup) 
            { 
                RadComboBoxItem i = new RadComboBoxItem(); 
                i.Text = group.Title; 
                i.Value = String.Empty; 
                i.CssClass = "comboitem group"
                i.Enabled = false
                comboBox.Items.Add(i); 
                lastGroup = group; 
                if (section != null
                { 
                    RadComboBoxItem si = new RadComboBoxItem(); 
                    si.Text = section.Title; 
                    si.Value = String.Empty; 
                    si.CssClass = "comboitem section"
                    si.Enabled = false
                    comboBox.Items.Add(si); 
                    lastSection = section; 
                } 
            } 
            else if ((section != null) && (section != lastSection)) 
            { 
                RadComboBoxItem si = new RadComboBoxItem(); 
                si.Text = section.Title; 
                si.Value = String.Empty; 
                si.CssClass = "comboitem section"
                si.Enabled = false
                comboBox.Items.Add(si); 
                lastSection = section; 
            } 
            RadComboBoxItem j = new RadComboBoxItem(); 
            j.Text = ((IListItem)cf).Text; 
            j.Value = ((IListItem)cf).Value; 
            j.CssClass = "comboitem " + (section == null ? "groupitem" : "sectionitem"); 
            comboBox.Items.Add(j); 
        } 

  5. Steve
    Steve avatar
    1885 posts
    Member since:
    Dec 2008

    Posted 08 Mar 2010 Link to this post

    Hah, it did too, sorry :)

    Try moving that over to a webservice

    For example, if you look at the bytes transferred here you're averaging about 400 bytes each postback, while on the serverside load on demand you're looking at almost 1k (as seen here)...it's quite a drastic difference.

    I've also noticed that the expand\collapse animations add some lag when opening a large list
  6. Drew
    Drew avatar
    22 posts
    Member since:
    Mar 2009

    Posted 08 Mar 2010 Link to this post

    the load isnt the problem here, its the client-side searching/reaction time that is slow. the combobox is loaded only once:

    if (!Page.IsPostBack) 
            this.PopulateComboBox(baseReport.Fields); 

    are you saying we should load the data on-demand and search against the server every time? how would we handle showing all items (unfiltered)?





  7. Steve
    Steve avatar
    1885 posts
    Member since:
    Dec 2008

    Posted 08 Mar 2010 Link to this post

    Yes and no...

    My users table has 3600 records, and the webservice load on demand searches\filters (like the demo) almost instantly...the result being a google-like search and highlight.  So when they need to browse through all 1000 items, that's where the virtual scrolling comes into play and loads the rest of the items required....

    You'd have to play with it, but your page would defiantly Load faster since there isn't 1000 RadComboBox items being sent to the page even if they never open the combo.
  8. Kalina
    Admin
    Kalina avatar
    918 posts

    Posted 11 Mar 2010 Link to this post

    Hello Steve,

    Load-On-Demand feature loads items only when user types or clicks on the input field or on the arrow image of the RadComboBox – that is why it is the best approach to improve performance of the control.

    I can recommend you to retrieve data in portions - with use of ShowMoreResultsBox and VirtualScrolling options.

    Please take a look at this online example - it illustrates the usage of different Load On Demand modes.

    Note the GetData method at Default.aspx.cs in the example – implementation there allows the control to filter items, but at the same time keeps the option of showing all items unfiltered. If you prefer using a web service – the approach is similar to this.

    Greetings,
    Kalina
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  9. Lenny_shp
    Lenny_shp avatar
    343 posts
    Member since:
    Jul 2006

    Posted 15 Mar 2010 Link to this post

    Do you see any speed difference with 2010_1_312?

    I have the same issue, but I only have less than 700 items.


  10. Lenny_shp
    Lenny_shp avatar
    343 posts
    Member since:
    Jul 2006

    Posted 15 Mar 2010 Link to this post

    Can this demo page be made with 600 items?     It seems to contain only 91 items, which does not demonstrate well on how it scales.

    http://demos.telerik.com/aspnet-ajax/combobox/examples/populatingwithdata/autocompletesql/defaultcs.aspx
  11. Kalina
    Admin
    Kalina avatar
    918 posts

    Posted 16 Mar 2010 Link to this post

    Hello Lenny_shp,

    The examples that listed below illustrate usage of Load On Demand, ShowMoreResults and VirtualScrolling features.

    We have another online demo that demonstrates how to achieve the best performance with RadComboBox when dealing with large amounts of data (items) - you can find it here. 

    Greetings,
    Kalina
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  12. Lenny_shp
    Lenny_shp avatar
    343 posts
    Member since:
    Jul 2006

    Posted 16 Mar 2010 Link to this post

    The demo with 1,000 items doesn't have MarkFirstMatch enabled, to allow auto filtering of items when user types the first few characters.
  13. Steve
    Steve avatar
    1885 posts
    Member since:
    Dec 2008

    Posted 16 Mar 2010 Link to this post

    The LoadOnDemand does that..and better since you can have more control over it.  For example you could have the text values typed in check against (and return) multiple columns.  In my case I have almost twice the data because my template has username and email, and when they type into the box it hits the webservice, checks against both those cols, and returns the data instantly.

    If you only have a few hundred items just turn on Filter="Contains"
  14. Mouse
    Mouse avatar
    26 posts
    Member since:
    Sep 2009

    Posted 18 May 2010 Link to this post

    I have read this thread and i am also having the same problem.
    My ComboBox has about 1000 items in it.

    The thing i dont understand is - why have a filter feature if you cant use it on big loads of data?

    Surely the whole point of filtering is to make large amounts of data small and readable.

    If i have a small amount of data i could just look through it without having to start typing what i want into the combobox.

  15. Steve
    Steve avatar
    1885 posts
    Member since:
    Dec 2008

    Posted 18 May 2010 Link to this post

    That is the point of filtering, however the tons of items in the combo are adding to the size of your DOM, and thus increasing the processing time to look through those items.

    However if you implement webservice filtering and\or load on demand you have zero DOM and just load in what you need...so if you only need "Bob Jones" from the combobox, why load in the other 999 names...
  16. Kalina
    Admin
    Kalina avatar
    918 posts

    Posted 19 May 2010 Link to this post

    Hi,

    Indeed, Load on Demand filters the Items server-side before they are loaded in the control and the Filter feature performs filtering at client-side.

    That is why the best approach to optimize the performance speed of the RadComboBox when dealing with large amount of data is to use the Load on Demand feature.  


    All the best,
    Kalina
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  17. Sam
    Sam avatar
    27 posts
    Member since:
    Dec 2010

    Posted 15 Dec 2010 Link to this post

    Hi Kalina,

    If you filter the items at server - side, after you type one key in the input of RadComboBox, the server - side have to connect a database to filter the text. If my site have 1.000.000 user filter a text at the same time, 1.000.000 connection being created. I think that is a problem.
    Why do you filter the text at client - side to all items using javascript? I think using javascript to compare the text between 1k ~ 5k items is not a problem.

    Thanks for reading!
  18. Steve
    Steve avatar
    1885 posts
    Member since:
    Dec 2008

    Posted 15 Dec 2010 Link to this post

    Hey Sam :)

    It's highly unlikely that a million people would be on your site all using the same control at the exact same time...I would argue almost impossible unless you're google.  However SQL should still be able to handle a simple select\filter query without breaking a sweat :)  You're server environment should be severely load balanced anyway if you're planning on that kind of traffic.  SQL uses connection pooling anyway...

    If you put 5000+ items clientside you're DRASTICALLY increasing the size of your markup, so even if the user doesn't use that combo they're getting a bloated page.  Browser will download the html, then parse out what it needs to display, so the longer it takes for the html to get there (and the larger the size) the slower your page will appear to load.  Even firebug will start to chug if the markup is too large.

    Also (right now anyway) the clientside filtering on large results is pretty slow...I think they're working on speeding it up right now.

    Webservice binding is the fastest way atm to keep your markup clean and filter large resultsets unquestioned.
  19. Sam
    Sam avatar
    27 posts
    Member since:
    Dec 2010

    Posted 16 Dec 2010 Link to this post

    Hi Steve,

    Now, I am using Web service and caching the data at first page load then filter the text on this cache. I hope The Telerik Team fix it in the furture.

    Thanks for your response!
Back to Top