EasyUI Forum
April 26, 2024, 11:43:26 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News:
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Performance issue while switching between tabs  (Read 5198 times)
gordis gmbh
Full Member
***
Posts: 103


View Profile Email
« on: October 02, 2017, 01:46:50 AM »

I have few nested tabs with a datagrid in each of these lower tabs.
These datagrids are loaded lazily i.e. only then when tabs are selected and can have max 200 rows each. The no. columns in datagrid can vary between 5 and 10. After loading few datagrids, the switching between these tabs take upto 5 seconds. In Chrome its bit quicker, in IE (tested in version 11) it takes even longer.

The following fiddle demonstrates the issue: http://jsfiddle.net/6NXjB/26/

To see the problem:
Click on a few "Platform Instance" tabs and then try switching between tabs "My Platforms" and "My Apps" or between "Platform 1" and "Platform 2"

Why does it take that long?
Thanks for checking this one out!
Logged
gordis gmbh
Full Member
***
Posts: 103


View Profile Email
« Reply #1 on: November 01, 2017, 01:32:41 AM »

After analysing the source code of easyui, I found that the reason that causes a delay in switching tabs which contain 'n' number of tabs within, is due to 'unnecessary' calls to resize the panel.

In order to fix this performance issue, I made adjustments in the following two source-files of easyui:
- jquery.panel.js
- jquery.tabs.js

In jquery.panel.js I made the following two changes:

1. Adjusted setSize function to avoid unnecessary resize
2. Adjusted openPanel.cb function to avoid repeated call to loadData and doLayout if collapse is set to false

Code:

function setSize(target, param){
var state = $.data(target, 'panel');
var opts = state.options;
var panel = state.panel;
var pheader = panel.children('.panel-header');
var pbody = panel.children('.panel-body');
var pfooter = panel.children('.panel-footer');
// -------------------START: Code changed by Gordis GmbH--------------------- //
if(opts.prevWidth && param) {
// prevWidth exists. that means setSize is already called once for this panel. Now proceed only if any one of the params (width,height,minWidth etc.) has changed
if(opts.prevWidth == param.width
&& opts.prevHeight == param.height
&& opts.prevMinWidth == param.minWidth
&& opts.prevMaxWidth == param.maxWidth
&& opts.prevMinHeight == param.minHeight
&& opts.prevMaxHeight == param.maxHeight
&& opts.prevLeft == param.left
&& opts.prevTop == param.top) {
return;
}
}

if (param){
$.extend(opts, {
width: param.width,
height: param.height,
minWidth: param.minWidth,
maxWidth: param.maxWidth,
minHeight: param.minHeight,
maxHeight: param.maxHeight,
left: param.left,
top: param.top,
prevWidth: param.width,
prevHeight: param.height,
prevMinWidth: param.minWidth,
prevMaxWidth: param.maxWidth,
prevMinHeight: param.minHeight,
prevMaxHeight: param.maxHeight,
prevLeft: param.left,
prevTop: param.top,
});
}
// -------------------END: Code changed by Gordis GmbH--------------------- //
panel._size(opts);
pheader.add(pbody)._outerWidth(panel.width());
if (!isNaN(parseInt(opts.height))){
pbody._outerHeight(panel.height() - pheader._outerHeight() - pfooter._outerHeight());
} else {
pbody.css('height', '');
var min = $.parser.parseValue('minHeight', opts.minHeight, panel.parent());
var max = $.parser.parseValue('maxHeight', opts.maxHeight, panel.parent());
var distance = pheader._outerHeight() + pfooter._outerHeight() + panel._outerHeight() - panel.height();
pbody._size('minHeight', min ? (min - distance) : '');
pbody._size('maxHeight', max ? (max - distance) : '');
}
panel.css({
height: '',
minHeight: '',
maxHeight: '',
left: opts.left,
top: opts.top
});

opts.onResize.apply(target, [opts.width, opts.height]);

$(target).panel('doLayout');
// $(target).find('>div:visible,>form>div:visible').triggerHandler('_resize');
}



function openPanel(target, forceOpen){
var opts = $.data(target, 'panel').options;
var panel = $.data(target, 'panel').panel;

if (forceOpen != true){
if (opts.onBeforeOpen.call(target) == false) return;
}
panel.stop(true, true);
if ($.isFunction(opts.openAnimation)){
opts.openAnimation.call(target, cb);
} else {
switch(opts.openAnimation){
case 'slide':
panel.slideDown(opts.openDuration, cb);
break;
case 'fade':
panel.fadeIn(opts.openDuration, cb);
break;
case 'show':
panel.show(opts.openDuration, cb);
break;
default:
panel.show();
cb();
}
}

function cb(){
opts.closed = false;
opts.minimized = false;
var tool = panel.children('.panel-header').find('a.panel-tool-restore');
if (tool.length){
opts.maximized = true;
}
opts.onOpen.call(target);

if (opts.maximized == true) {
opts.maximized = false;
maximizePanel(target);
}
if (opts.collapsed == true) {
opts.collapsed = false;
collapsePanel(target);
}

// -------------------START: Code changed by Gordis GmbH--------------------- //
if (!opts.collapsed){
if(opts.loadDataDoLayoutDone == true) {
return;
}
loadData(target);
doLayout(target);
opts.loadDataDoLayoutDone = true;
}
// -------------------END: Code changed by Gordis GmbH--------------------- //
}
}

In jquery.tabs.js I adjusted the setSelectedSize function to avoid unnecessary calls to tabpanel-resize:

Code:
	/**
* set selected tab panel size
*/
function setSelectedSize(container){
var opts = $.data(container, 'tabs').options;
var tab = getSelectedTab(container);
if (tab){
var panels = $(container).children('div.tabs-panels');
var width = opts.width=='auto' ? 'auto' : panels.width();
var height = opts.height=='auto' ? 'auto' : panels.height();
// -------------------START: Code changed by Gordis GmbH--------------------- //
var tabPanelOpts = tab.panel('options');
if(tabPanelOpts.prevWidth) {
// prevWidth exists, now proceed with resize only if width or height has changed!
if(tabPanelOpts.prevWidth == width && tabPanelOpts.prevHeight == height)
return;
}

tab.panel('resize', {
width: width,
height: height
});
tabPanelOpts.prevWidth = width;
tabPanelOpts.prevHeight = height;
// -------------------END: Code changed by Gordis GmbH--------------------- //
}
}

We at Gordis are testing the code, looks good so far. The switching between tabs is enormously improved (especially in IE). The resize of panel/tabs does get triggered if there is a change in the size (for e.g. if i change the size of browser). Collapse /open of panel works as desired.

Questions @easyi-ui owners/experts:
1. Does the changes made above makes sense?
2. Are there any consequences which I haven't yet located?
3. If the changes made above makes sense, will they be adopted in the coming version or made available as a patch?

Please let me know.
« Last Edit: November 01, 2017, 01:40:20 AM by gordis gmbh » Logged
stworthy
Administrator
Hero Member
*****
Posts: 3581


View Profile Email
« Reply #2 on: November 01, 2017, 06:49:35 PM »

Thank you for your hard work. Yes, the way to improve the performance is to avoid duplicate calling the 'resize' method. Only detecting the resizing parameters such as 'width' and 'height' may cause some undesired issue because the same '100%' value may have different size. Some code has been modified and the patch can be downloaded from https://www.jeasyui.com/download/downloads/jquery-easyui-1.5.3-patch.zip
Logged
gordis gmbh
Full Member
***
Posts: 103


View Profile Email
« Reply #3 on: November 02, 2017, 02:50:45 AM »

Thanks Stworthy for looking into the matter and for the patch. I will test the patch asap and feedback.
Logged
gordis gmbh
Full Member
***
Posts: 103


View Profile Email
« Reply #4 on: November 03, 2017, 07:19:36 AM »

The patch works great! Thanks once again for the timely support!!
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!