Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery width() method performance

I'm a jQuery noob trying to track down a performance issue that we're having with large tables. We have a homegrown table widget which, among other things, sets the column widths to the max of the header width or the rows width.

With a table of 10 rows by 500 columns, this can take almost 40 seconds (!) which seems excessive given that the table can be rendered in under 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 replace

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

with a constant

    var commonWidth = 100;

the execution time drops from 38 seconds to under a second, indicating that the issue is on reading/calculating the current widths as opposed to setting the new width. From the profiling/sampling that I've done, it appears that jQuery is spending an inordinate amount of time messing around with CSS calculations.

Can anyone recommend a more efficient way to do this?

EDIT:

I've tried both css("width") and outerWidth() without any significant changes in performance. We were using jQuery 1.7.2, but upgrading to 1.8.1 didn't change performance significantly.

like image 943
Tom Morris Avatar asked Dec 19 '25 09:12

Tom Morris


1 Answers

Use .css("width") instead of .width(), changes were made to the .width() method that make it perform 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()
);
like image 149
Kevin B Avatar answered Dec 21 '25 02:12

Kevin B