【问题标题】:Can this jQuery be modified to run faster?可以修改这个 jQuery 以更快地运行吗?
【发布时间】:2011-08-30 14:16:49
【问题描述】:

以下 jQuery each 函数导致 IE8 显示“停止运行脚本?..此页面上的脚本导致浏览器运行缓慢..”消息。

$('.expand-collapse-icon').each(function() {
    var dupId = $(this).parent('td').attr('duplicate-id');

    var len = $(".results-table tr")
        .filter(":not(:first)")
        .filter(":has(.hidden-row[duplicate-id='" + dupId + "'])").length;

    if (len <= 0) {
        $(this).hide();
        $(this).parent('td').css('padding-left', '15px');
    }
});

基本上,我有许多可见的行(大约 92 个),它们具有相关的隐藏行。这些行由duplicate-id 关联每个可见行在第一个&lt;td&gt; 中都有一个expand-collapse-icon。如果单击该图标,它将显示隐藏的行。如果可见行没有关联的隐藏行,我不想显示图标。

理想情况下,如果没有关联的行,我可以阻止页面在服务器端显示图标,但是代码中潜伏着龙。

有什么明显的方法可以加快速度吗?

【问题讨论】:

  • 这段代码什么时候运行?准备好文件了吗?你能发布一些html作为例子吗?

标签: jquery performance internet-explorer


【解决方案1】:

可以肯定的是,在函数的开头删除多个 $(this) - "cache" this 语句值。例如:

var $this = $(this);

现在你的脚本每次迭代都会在 jQuery 中包装同一个对象 3 次 - 很乱!

我想到的其他事情 - 一般来说,.each 方法很慢,比简单地遍历 $(".some-选择器示例”)。 编辑:我找到了文章 10 ways to instantly increase jQuery performance,虽然它现在已经很老了(从 2009 年开始),但仍然建议使用大多数(如果不是全部)提示。特别仔细查看图表,该图表显示了 .each 方法与相同数据集合上的常规循环相比的性能。

最后一件事可能是脚本中最影响性能的问题 - len = $(".results-table tr").filter(":not(:first)")选择。您可以做的是至少保留选择部分的结果(将此变量保留在您正在迭代的函数之外):

var cached_trs = $(".results-table tr").filter(":not(:first)");

然后在您正在迭代的函数中,您可以使用过滤器进行操作:

var len = cached_trs.filter(":has(.hidden-row[duplicate-id='" + dupId + "'])").length

【讨论】:

    【解决方案2】:

    试试这个。在这里,我缓存了大部分重复的元素提取,避免了通过.hiddne-row 类过滤行并且只搜索一次,然后只在循环内按属性过滤,这是一个重大改进,因为属性 FET 与其他的比较慢。使用 :gt(0) 而不是 `:not(:first)' 也只能在循环外使用一次。

    var $this, $parent, dupId, len ;
    
    //This line will get all the rows from .resutls-table 
    //filtered by ":not(:first):has(.hidden-row)"
    //That way you dont have to search for trs and filter it everytime in the loop
    var $resultsTr = $(".results-table tr.hidden-row:gt(0)");
    
    $('.expand-collapse-icon').each(function() {
        $this = $(this);
        $parent = $this.parent('td');
        dupId = $parent.attr('duplicate-id');
    
        len = $resultsTr
            .filter("[duplicate-id='" + dupId + "'])").length;
    
        if (len <= 0) {
            $this.hide();
            $parent.css('padding-left', '15px');
        }
    });
    

    【讨论】:

    • @mblase75 - 你在代码中看到$parent 在两个不同的地方使用,所以缓存它是有意义的。
    • 并且,作为一个小的优化,.results-table 类可能应该是一个 ID,因为从他的描述中听起来好像页面中只有一个这样的表。
    • @mblase75,我没有指定,但可以有多个表。
    【解决方案3】:

    您使用了太多相同的 jQuery 选择器。

    您可以通过将多次使用的变量存储在一个变量中来进行优化。

    $('.expand-collapse-icon').each(function() {
    
        var $this = $(this);
        var $parent = $this.parent('td');
        var dupId = $parent.attr('duplicate-id');
    
        var len = $(".results-table tr")
            .filter(":not(:first)")
            .filter(":has(.hidden-row[duplicate-id='" + dupId + "'])").length;
    
        if (len <= 0) {
            $this.hide();
            $parent.css('padding-left', '15px');
        }
    
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-11
      • 2011-07-07
      • 1970-01-01
      • 2012-06-27
      • 1970-01-01
      • 1970-01-01
      • 2016-04-23
      • 2016-02-19
      相关资源
      最近更新 更多