1. #1
    Sencha User
    Join Date
    Mar 2011
    Posts
    115
    Vote Rating
    131
    fdp is a name known to all fdp is a name known to all fdp is a name known to all fdp is a name known to all fdp is a name known to all fdp is a name known to all

      0  

    Default How to improve performance of a Combobox with a large store with local queryMode

    How to improve performance of a Combobox with a large store with local queryMode


    Hi people,

    I spent almost half a day to solve a bad performance issue with a combobox with a very large store, I would share my solution with the community to give my small contribute.

    This my basic combobox
    Code:
    xtype: 'combobox',
    name: 'code',
    store: Ext.create('Ext.data.Store', {
      autoLoad: true,
      fields: ['code'],
      proxy: {
        type: 'ajax',
        url : 'codes.json',
        reader: 'array'
      }
    }),
    queryMode: 'local',
    minChars: 1,
    hideTrigger: true,
    forceSelection: 'true',
    typeAhead: 'true',
    displayField: 'code',
    valueField: 'code',
    allowBlank: false,
    fieldLabel: 'Code',
    This is my codes.json with about 15000+ items
    Code:
    [["C001"],["D230"],["Z777"]...]
    I know i could use querymodel=remote and write a serverside script to serve the combo but for my scenario it is much better to use a querymode=local without any http request. My json is less then 100kb and will not change so i preferer a single http request that could be also cached by the browser.

    The performance problem is that when the user clicks on the combobox trigger, it freeze for about 3-4 seconds and then it shows the picker, this was not acceptable for my users.

    I did several things to improve performance, even using the really nice page-analyzer but was unable to fast find the problem so i did a deeper debug of ext source code and finally found that the problem is all here:

    Code fragment from Ext.form.field.ComboBox
    Code:
    ...
            // query permitted to run
            if (forceAll || (queryString.length >= me.minChars)) {
                // expand before starting query so LoadMask can position itself correctly
                me.expand();
    
    
                // make sure they aren't querying the same thing
                if (!me.queryCaching || me.lastQuery !== queryString) {
    ...
    me.expand() is a nightmare because even with minChars it renders all the items (15k+) and re-render again with the queryString!

    It was hard to do a non intrusive fix but I think this could be an easy workaround until this got fixed (it is not a bug but a performance issue).

    New combobox that is cached by the browser and without performance issue:
    Code:
    xtype: 'combobox',
    name: 'code',
    store: Ext.create('Ext.data.Store', {
      autoLoad: true,
      fields: ['code'],
      proxy: {
        type: 'ajax',
        url : 'codes.json',
        pageParam: '',  // allow browser cache
        limitParam: '', // allow browser cache
        startParam: '', // allow browser cache
        noCache: false, // allow browser cache
        reader: 'array'
      },
      filterOnLoad: true,         // prevent expand performance issue
      filters: [                  // prevent expand performance issue
        function(item) {          // prevent expand performance issue
          return item.index < 20; // prevent expand performance issue
        }                         // prevent expand performance issue
      ]                           // prevent expand performance issue
    })
    queryMode: 'local',
    activeFilter: true, // workaround to allow me.clearFilter() inside Ext.form.field.ComboBox
    minChars: 1,
    hideTrigger: true,
    forceSelection: 'true',
    typeAhead: 'true',
    displayField: 'code',
    valueField: 'code',
    allowBlank: false,
    fieldLabel: 'Code',
    Now the combobox is responsive because it load just 20 records to allow expand sizing and the minChars 1 is really applied.

    I Hope this could save time to someone, feel free to suggest also more improvements, bye.

  2. #2
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    9,197
    Vote Rating
    482
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    Thank you for the write up. I am sure others will find it helpful. Other solutions include using a paginated grid in the combo list.

    Regards,
    Scott.

  3. #3
    Sencha User
    Join Date
    Mar 2011
    Posts
    115
    Vote Rating
    131
    fdp is a name known to all fdp is a name known to all fdp is a name known to all fdp is a name known to all fdp is a name known to all fdp is a name known to all

      0  

    Default


    Hi scott,

    Thanks for the hint but the problem occurs even with pagination (with local querymode), with remote it is ok but as said my goal is to use local.

  4. #4
    Sencha User
    Join Date
    Mar 2008
    Posts
    19
    Vote Rating
    0
    Vikram is on a distinguished road

      0  

    Default


    Nice post, but still not able to understand where to add the following code for combobox

    // query permitted to run
    if (forceAll || (queryString.length >= me.minChars)) {
    // expand before starting query so LoadMask can position itself correctly me.expand();
    // make sure they aren't querying the same thing
    if (!me.queryCaching || me.lastQuery !== queryString) {

Thread Participants: 2

Tags for this Thread