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.jsIn 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
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: /**
* 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.