使用jQuery格式化表非常慢

时间:2013-06-10 09:43:24

标签: javascript jquery html css

我有一个表格,其中有一个切换显示/隐藏符合特定条件的各种行,我使用以下JS来实现我想要的(JSFiddle);

function resetRows() {
    var i = 1,
        tds;
    var start = new Date().getTime();
    $('td').removeClass('even odd');

    $.each($('tr'), function (key, index) {
        // loop through each table row skipping the first row which will be the title
        tds = $(this).find($('td'));
        if ($(this).is(':visible') && key > 0) {
            if (i % 2 === 0) {
                tds.addClass('even');
            } else {
                tds.addClass('odd');
            }
            // find the .index class and reset it's value
            $(this).find($('.index')).html(i);
            i++;
        }
    });
    var end = new Date().getTime();
    var time = end - start;
    console.log('time taken: ' + time);
}

$(function () {

    // show/hide failed
    $('#showHideFails').on('click', function () {
        if ($('.failed').eq(0).is(':visible')) {
            $('.failed, .ins').hide();
            $('.shTxt').html('Show all');
            resetRows();
        } else {
            $('.failed, .ins').show();
            $('.shTxt').html('Hide failed');
            resetRows();
        }
    });

});

我的问题是这段代码执行得非常慢。 js小提琴相对较快,因为我的示例表只有15行。我的实际表格有100行,可以更改为显示1,000行。

我已经添加了一个控制台日志来测试它执行了多长时间,并且在小提琴中它需要大约15ms来隐藏行,并且~20-40ms再次显示行。< / p>

在我的真实桌子上有100行,这个变化为~300-450ms隐藏和~500-600ms显示。尝试200行(分别为1,200和2,00)时,这个数字增加了一倍多。当我尝试1000行时,我的浏览器几乎崩溃了。

我尝试更改我的代码,以便不改变td的类名,而是改变了tr的类名,理论上这意味着jQuery处理所需的处理较少,但这几乎使执行时间翻了一倍,所以我又回到了td

有谁能告诉我如何提高我的代码效率?获得我想要的功能有点令人沮丧,只是让它运行得非常慢。

2 个答案:

答案 0 :(得分:2)

使用这种元素迭代时,应该从DOM中分离表。然后,您可以在任务期间向用户显示任何消息,如加载程序。

http://jsfiddle.net/ZYsHL/6/

function resetRows($table) {
    var $loader = $('<div id="loader"/>').insertBefore($table),
        $tblContent = $table.detach(),
        i = 1,
        trs = $tblContent.find('tr'),
        tds = $tblContent.find('td').removeClass('even odd');
    var start = new Date().getTime();

    $.each(trs, function (key, index) {
        // loop through each table row skipping the first row which will be the title
        var tdsRow = $(this).find('td');

        if (!$(this).data('hidden') && key > 0) {
            if (i % 2 === 0) {
                tdsRow.addClass('even');
            } else {
                tdsRow.addClass('odd');
            }
            // find the .index class and reset it's value
            $(this).find('.index').html(i);
            i++;
            console.log(i);
        }
    });
    var end = new Date().getTime();
    var time = end - start;
    $loader.replaceWith($table);
    console.log('time taken: ' + time);
}

$(function () {

    // show/hide failed
    $('#showHideFails').on('click', function () {
        if ($('.failed').eq(0).is(':visible')) {
            $('.failed, .ins').data('hidden',true).hide();
            $('.shTxt').html('Show all');
            resetRows($('#table'));
        } else {
            $('.failed, .ins').data('hidden',false).show();
            $('.shTxt').html('Hide failed');
            resetRows($('#table'));
        }
    });

});

答案 1 :(得分:1)

一些代码优化建议:

  1. 使用.find()

    tds = $(this).find($('td'));tds = $(this).find('td')

    相同 在执行任何其他操作之前,

    $('td')会导致jquery在整个HTML 中搜索所有表格单元格

    但你真正想要的是:当前行的所有单元格可以用$(this).find('td')

  2. 完成
  3. 删除“死”代码

    如果您在标题行中或者行已被隐藏,那么您的行迭代函数 nothing 。此时您正在搜索该行中的单元格,即使它已被隐藏。

     $.each($('tr'), function (key, index) {
        if (false == $(this).is(':visible') || 0 == key) {
            // skip hidden rows and header row
            return;
        }
    
        // at this point we know that the current row is visible and not the header row
        tds = $(this).find($('td'));
        ...
     });
    
  4. 减少jQuery选择器

    据我所知,选择器是这里成本最高的部分。虽然这对于小数据来说不是问题,但它可以影响大型数据,例如1000行等表。尝试使用变量重新使用选择器结果。

    将$(this)替换为变量:

    var currentRow = $(this);
    currentRow.is(':visible');
    currentRow.find('td');
    ...
    
  5. 到目前为止,这是我的想法。请参阅此jsfiddle以获取重写代码:http://jsfiddle.net/5jVdh/3/