EasyUI Forum
May 17, 2024, 10:13:11 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News:
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Datagrid enableFilter performance problem  (Read 15276 times)
hande89
Jr. Member
**
Posts: 56


View Profile
« on: February 16, 2015, 07:28:07 AM »

If I take this example: http://www.jeasyui.com/tutorial/datagrid/datagrid30_demo.html and copy paste columns so that there are 36 of them in total... Then this measurement shows that initializing the filter component is taking 2,6 seconds in Firefox and 3,1 in Chrome, using latest browser versions...

Code:
$(function(){
                        var d = new Date();
var dg = $('#dg').datagrid();
dg.datagrid('enableFilter', [{
field:'listprice',
type:'numberbox',
options:{precision:1},
op:['equal','notequal','less','greater']
},{
field:'unitcost',
type:'numberbox',
options:{precision:1},
op:['equal','notequal','less','greater']
},{
field:'status',
type:'combobox',
options:{
panelHeight:'auto',
data:[{value:'',text:'All'},{value:'P',text:'P'},{value:'N',text:'N'}],
onChange:function(value){
if (value == ''){
dg.datagrid('removeFilterRule', 'status');
} else {
dg.datagrid('addFilterRule', {
field: 'status',
op: 'equal',
value: value
});
}
dg.datagrid('doFilter');
}
}
}]);
                        console.log(new Date()-d);
});

What is wrong?
Logged
hande89
Jr. Member
**
Posts: 56


View Profile
« Reply #1 on: February 20, 2015, 01:42:12 AM »

After examining the datagrid filter code I noticed that this loop in createFilterButton method is taking a long time:

Code:
			$.each(['nofilter'].concat(operators), function(index,item){
var op = opts.operators[item];
if (op){
menu.menu('appendItem', {
text: op.text,
name: item
});
}
});

If I replace this with native Javascript for loop, time improves ~ < 0.1 s...

but also in in jquery.menu.js there is

Code:
$.fn.menu.methods={
appendItem:function(jq,_56){
return jq.each(function(){
_3a(this,_56);
});
}};

I think you should not use jQuery each because it can be much slower than the native loop.

http://code.tutsplus.com/tutorials/10-ways-to-instantly-increase-your-jquery-performance--net-5551

Quote
jQuery's each function takes over 10 times as long as JS native "for" loop. This will certainly increase when dealing with more complicated stuff, like setting CSS attributes or other DOM manipulation operations.

Edit: maybe the problem is more with this line in createFilter method

Code:
input.addClass('datagrid-filter').attr('name', field);

Changing it to this:

Code:
var input_tmp = input[0];
input_tmp.setAttribute('class',input_tmp.className += ' datagrid-filter');
input.attr('name', field);

improved time by 0,5 seconds! http://www.zachleat.com/web/quick-performance-tip-jquery-and-addclass/

Another half a second can be gained by removing this line from the for loop there:
Code:
resizeFilter(target, field);
« Last Edit: February 24, 2015, 02:26:15 AM by hande89 » Logged
phunksta
Jr. Member
**
Posts: 54


View Profile Email
« Reply #2 on: March 06, 2015, 03:57:03 AM »

Thanks for this, I'm going to go and try some of this stuff now!

When I tried to analyse my 5-6 second initialisation on datagrid-filters, I see thousands of these browser reflow events:

"Forced synchronous layout is a possible performance bottleneck."
Usually, this is to do with 'getWidthOrHeight' and offsetHeight / width.

There certainly seems like some optimisation is needed on this extension.

See the attached for a snapshot of the type of event coming up in the broswer timeline analysis.
Logged
hande89
Jr. Member
**
Posts: 56


View Profile
« Reply #3 on: March 17, 2015, 10:48:34 AM »

In my real application some of the columns are almost always hidden. I think the filter component should not be created for a column if it is hidden when enableFilter method is called. Only when the column becomes visible.
Logged
phunksta
Jr. Member
**
Posts: 54


View Profile Email
« Reply #4 on: March 18, 2015, 03:47:11 AM »

Ha freaky I was just thinking about letting my users hide some of their columns to increase performance. i'm glad I didn't spend much time with that idea!

Is there anyone from the easyUI team who could comment about improving performance when using the datagrid-filters extension?
Logged
hande89
Jr. Member
**
Posts: 56


View Profile
« Reply #5 on: March 30, 2015, 05:09:32 AM »

It seems that also the doFilter method is taking a long time, at least if using remote filtering because it calls the load method.

Code:
	function doFilter(target){
var name = getPluginName(target);
var state = $.data(target, name);
var opts = state.options;
if (opts.remoteFilter){
       $(target)[name]('load');
} else {
$(target)[name]('getPager').pagination('refresh', {pageNumber:1});
$(target)[name]('options').pageNumber = 1;
$(target)[name]('loadData', state.filterSource || state.data);
}
}

The request is fast, my server is not a problem. If I comment out this line, time improves by 0,5 seconds:

Code:
$(target)[name]('load');

But then it of course does not work like it should.
« Last Edit: March 30, 2015, 07:50:15 AM by hande89 » Logged
hande89
Jr. Member
**
Posts: 56


View Profile
« Reply #6 on: April 08, 2015, 02:53:59 AM »

Another example of wrong usage of jQuery in easyui.min.js is the setIcon method of the menu component, affects to filter initialization as well

Code:
setIcon:function(jq,_418){
return jq.each(function(){
$(_418.target).children("div.menu-icon").remove();
if(_418.iconCls){
$("<div class=\"menu-icon\"></div>").addClass(_418.iconCls).appendTo(_418.target);
}
});

Could be

Code:
setIcon:function(jq,_418){
$(_418.target).children("div.menu-icon").remove();
$('<div class="menu-icon ' +_418.iconCls+'"></div>').appendTo(_418.target);
}

Effect is a few tenths of second.
Logged
hande89
Jr. Member
**
Posts: 56


View Profile
« Reply #7 on: April 21, 2015, 02:02:59 AM »

$.map can also be replaced with for loop, for example

Code:
$.map(opts.filterRules, function(rule){
addFilterRule(target, rule);
});

This should be much faster

Code:
for(var i=0;i<opts.filterRules.length;i++) addFilterRule(target,opts.filterRules[i]);

http://stackoverflow.com/questions/6551139/jquery-map-vs-javascript-map-vs-for-loop
Logged
hande89
Jr. Member
**
Posts: 56


View Profile
« Reply #8 on: April 29, 2015, 11:59:36 PM »

Is there anyone from the easyUI team who could comment about improving performance when using the datagrid-filters extension?

I think we must buy the commercial version to get this fixed properly...
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines Valid XHTML 1.0! Valid CSS!