JQuery width () method efficiency

I am jQuery noob trying to track the performance issue that we have with large tables. We have a home table widget that, by the way, sets the column width to the maximum header width or row width.

With a table of 10 rows per 500 columns, this can take almost 40 seconds (!), Which seems excessive given that the table can be displayed in less than a second.

Here's the whole function:

var dataTable = this._div.find('.data-table'); var headerTable = this._div.find('.data-header-table'); if (dataTable.length === 0 || headerTable.length === 0) { return; } dataTable = dataTable[0]; headerTable = headerTable[0]; if (dataTable.rows.length === 0) { return; } var dataTr = dataTable.rows[0]; var headerTr = headerTable.rows[headerTable.rows.length - 1]; var marginColumnWidths = $(dataTr.cells[0]).outerWidth(true) + $(dataTr.cells[1]).outerWidth(true) + $(dataTr.cells[2]).outerWidth(true) - DOM.getHPaddings($(headerTr.cells[0])) + 1; $(headerTable) .find('> tbody > tr > td:first-child') .width('1%') .children() .first() .width(marginColumnWidths); for (var i = 1; i < headerTr.cells.length; i++) { var headerTd = $(headerTr.cells[i]); var dataTd = $(dataTr.cells[i + 2]); var commonWidth = Math.max( Math.min(headerTd.width(), 100), dataTd.width() ); headerTd.width('1%').find('> div').width(commonWidth); dataTd.children().first().width(commonWidth); } 

If I replaced

  var commonWidth = Math.max( Math.min(headerTd.width(), 100), dataTd.width() ); 

with constant

  var commonWidth = 100; 

the execution time is reduced from 38 seconds to a second, which indicates that the problem is with reading / calculating the current width, and not with setting a new width. From the profiling / fetching I've done, it seems like jQuery is spending an excessive amount of time using CSS computations.

Can a more efficient way to do this be recommended?

EDIT:

I tried both css ("width") and outerWidth () without any significant performance changes. We used jQuery 1.7.2, but updating to 1.8.1 did not affect performance much.

+2
performance jquery
source share
3 answers

Use .css("width") instead of .width() , changes have been made to the .width() method, which makes it run slower. Read this for more information: http://blog.jquery.com/2012/08/16/jquery-1-8-box-sizing-width-csswidth-and-outerwidth/

 var commonWidth = Math.max( Math.min(parseFloat(headerTd.css("width")), 100), dataTd.width() ); 
+8
source share

As I know - .width() takes the real width (not always one set in css), and to get it - the browser must calculate it (forced redrawing the page and calculating the width itself). Now you set the width, the browser should redraw everything. It can do this with a slight delay, but in the next step you will get the width again - the browser MUST redraw the page to get the actual width. Read the width first, and then - in another cycle, set the calculated values. I think this should help

EDIT

It is tested in comparison with Kelvin B. The difference is not significant. It seems that it is best to use css ("width"). Here are the tests: Hectometer Tested this. Compared to the approach I suggested. It turned out that the difference is small. Here is a test: the width of one loop , css width one loop , css two loops , the width of two loops . The result is almost no difference. The slowest is the "width of one loop". The fastest is one of those with css . From time to time me more than once.

Note: four different case tests, because it looks like js perf, does not figure out the state of html between test cases.

Not sure what can be done in your case, but what I see is strange .width('1%') you use. It seems to me that you do not need it, so maybe you can try to remove it.

+2
source share

if you do .width (as well as .css ("width")) on the table cell (or headers) of very large tables, it takes a very long time for hidden elements !!!, and very fast for visible elements. The reason is that if the element is hidden, the browser, being beautiful and effective, did not make any effort to figure out how wide it would be if the element were visible. But jQuery.width, apparently for hidden elements, returns what would be the width if it were visible, instead of just returning zero (it is hidden in order). For large tables, this means that the browser should display the entire table again. If the table is really large, it may take more than a second. And if you do this for a few hidden columns (just by measuring their width), your page will become useless.

therefore, do not measure the width of hidden elements unless you SHOULD know.

relevant link, repeating what I just said (and much more): here

+1
source share

All Articles