PDA

View Full Version : Faster column resizing/positioning using float:left on cells


glassy
11-27-2006, 07:59 AM
I've run into the same performance issue that this thread refers to:
http://www.yui-ext.com/forum/viewtopic.php?t=199
(When there are lots of columns, it takes very long to resize them.)

And it gets worse when there are lots of rows.
Also it takes more time to resize columns on the left than columns on the right, probably because there are more cells to reposition.

The solution I came up with to speed it up is to use float: left on cells instead of absolute positioning all of them. This way when a column is resized, only the cell widths of a single column needs to be updated, and all the cells on the right will reposition themselves automatically because of float: left

The short version of the fix which can be easily pasted in html files is:



<style>
.ygrid-col{
position: static; /* use float: left instead of position: absolute; */
float: left;
}
</style>

<script>
YAHOO.ext.grid.GridView.prototype.setCSSWidth = function(colIndex, width, pos) {
var selector = ["#" + this.grid.id + " .ygrid-col-" + colIndex, ".ygrid-col-" + colIndex];
YAHOO.ext.util.CSS.updateRule(selector, 'width', width + 'px');
/* the following is commented out from original
because when we use float: left, we don't need to set positions
if(typeof pos == 'number'){
YAHOO.ext.util.CSS.updateRule(selector, 'left', pos + 'px');
}
*/
}
</script>



The result after this change is that column resizes are now a lot faster when there are lots of columns/rows. Also the speed of resizing the first and last columns are the same.

The only problem is that when using the code above in IE in Strict Mode, the headers and the cells don't line up right because of box model differences. (IE doesn't include the 1px left border in the width because it doesn't understand the box-sizing property.) This requires a small fix.

To see all this in action:

The original slow version:
http://www.viquasoft.com/yui-ext/examples/grid/array-grid-cols.html

The fast version using the code above (columns don't align properly in IE):
http://www.viquasoft.com/yui-ext/examples/grid/array-grid-cols-fast.html

The fast version with some small modifications so all browsers work the same in Strict Mode.
http://www.viquasoft.com/yui-ext/examples/grid/array-grid-cols-fast-fixed.html

If anyone has any comments whether this method has any drawbacks or problems, or any other suggestions that would be great!

The one drawback I can think of is that dynamic repositioning of columns won't be as easy as changing the absolute positions, it might require some rearranging in the DOM (I'm not sure about that though .. )

jack.slocum
11-27-2006, 08:46 AM
It looks great. Do hidden columns still work?

The moving of columns could be addressed with a rerender (hopefully) when it gets done.

I originally used float, but there were a few problems with it. Sometimes the columns don't align. I found an interesting solution to the border problem when I created the propsgrid - use a background color on the parent cell and margins+background on the child (text). This kills the box sizing issue. I haven't had time to implement it yet in the main grid css.

The entire grid needs a refactor to use all the new functionality provided in yui-ext (such as DomHelper) and if I ever get the time I will be tackling it. When I do I will be sure to try integrating your solution here into the main codebase.

Thanks for sharing!

glassy
11-27-2006, 10:09 AM
It looks great. Do hidden columns still work?

Good question. I just tried it and without additional modifications, the columns on the right would just hang there as you can see here:
http://www.viquasoft.com/yui-ext/examples/grid/array-grid-cols-fast-fixed.html

(be sure to force refresh these since I updated the html and js files)

By changing the column hide/unhide methods to use display: none instead it seems to work ok:
http://www.viquasoft.com/yui-ext/examples/grid/array-grid-cols-fast-fixed-hidden.html

Also hiding/unhiding columns is a lot faster compared to the original:
http://www.viquasoft.com/yui-ext/examples/grid/array-grid-cols.html


The moving of columns could be addressed with a rerender (hopefully) when it gets done.

I originally used float, but there were a few problems with it. Sometimes the columns don't align. I found an interesting solution to the border problem when I created the propsgrid - use a background color on the parent cell and margins+background on the child (text). This kills the box sizing issue. I haven't had time to implement it yet in the main grid css.

The entire grid needs a refactor to use all the new functionality provided in yui-ext (such as DomHelper) and if I ever get the time I will be tackling it. When I do I will be sure to try integrating your solution here into the main codebase.

Thanks for sharing!

Sounds great!

awatkins
01-24-2007, 10:24 AM
Hey Jack and Glassy,

I have been trying to get the fast column rendering to work for the past couple of days in IE (works in Firefox). My columns don't align with the data well. After stripping my code and basically making it mirror Glassy's example, the alignment was still off. I just now figured out what could fix it. You must declare doctype to be strict: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">. If you take that out of the array-grid example, it no longer aligns well.

Problem I have is that I am using a Portal and I can't define the DOCTYPE (I can only write html that goes within the body of the page). Is there any known workaround for this problem? Thanks in advance.

mtran
03-08-2007, 02:33 PM
I made a small change to the above code and it seems to work in IE6 without strict mode.

// setting to width-1 to accomodate for the border (the first column doesn't need this)
if (YAHOO.ext.util.Browser.isIE && colIndex == 0) realWidth -= 1;
else if (!YAHOO.ext.util.Browser.isIE && colIndex > 0) realWidth -= 1;


So here the whole function again:

YAHOO.ext.grid.GridView.prototype.setCSSWidth = function(colIndex, width, pos) {
var selector = ["#" + this.grid.id + " .ygrid-col-" + colIndex, ".ygrid-col-" + colIndex];

realWidth = width;

// setting to width-1 to accomodate for the border (the first column doesn't need this)
if (YAHOO.ext.util.Browser.isIE && colIndex == 0) realWidth -= 1;
else if (!YAHOO.ext.util.Browser.isIE && colIndex > 0) realWidth -= 1;

YAHOO.ext.util.CSS.updateRule(selector, 'width', realWidth + 'px');
/* commented this out from original (updating the widths is enough, no need to update positions)
if(typeof pos == 'number'){
YAHOO.ext.util.CSS.updateRule(selector, 'left', pos + 'px');
}
*/
}


Thanks for the wonderful grid and this really slick speed boost :D

kalebwalton
03-09-2007, 02:52 PM
Jack, did this get incorporated into 1.0? I found it to be a very significant speed boost.

jack.slocum
03-10-2007, 02:45 AM
The new 1.0 grid has faster column resizing. It doesn't use floats, it uses a table.