【问题标题】:Speeding up jQuery empty() or replaceWith() Functions When Dealing with Large DOM Elements在处理大型 DOM 元素时加速 jQuery empty() 或 replaceWith() 函数
【发布时间】:2010-11-02 12:57:22
【问题描述】:

首先让我为没有提供代码 sn-p 道歉。我正在从事的项目是专有的,恐怕我无法准确地展示我正在从事的工作。不过,我会尽量做到描述性。

以下是我的应用程序中发生的情况的细分:

  1. 用户点击按钮
  2. 服务器以数据表的形式检索图像列表
  3. 表格中的每一行包含 8 个数据单元格,每个单元格又包含一个超链接
    • 用户的每个请求最多可以包含 50 行(如果需要,我可以更改此数字)
    • 这意味着该表包含超过 800 个单独的 DOM 元素
    • 我的分析表明,jQuery("#dataTable").empty()jQuery("#dataTable).replaceWith(tableCloneObject) 占用了我总处理时间的 97%,平均需要 4 到 6 秒才能完成。

在处理需要删除/替换的大量 DOM 元素时,我正在寻找一种方法来加速上述任何一个 jQuery 函数。希望我的解释有所帮助。

【问题讨论】:

    标签: javascript jquery dom performance


    【解决方案1】:

    对我有用的是$("#myTable").detach()。我必须清除一个有 1000 行的表。我试过$("#myTable").children().remove()。这是对$("myTable").empty() 的改进,但仍然很慢。 $("#myTable").detach() 需要 1 秒或更短的时间。 在 FF 和 Chrome 中运行良好。 IE还是很慢。

    【讨论】:

      【解决方案2】:

      jQuery empty() 在您的表上花费了很长时间,因为它对清空元素的内容进行了大量的工作,以防止内存泄漏。如果您可以承受这种风险,则可以跳过所涉及的逻辑,只需执行删除表格内容的部分,如下所示:

          while ( table.firstChild )
              table.removeChild( table.firstChild );
      

          table.children().remove();
      

      【讨论】:

      • 这行得通。我将针对可能的内存泄漏做更多的工作,但这完全加快了速度。谢谢大家!
      • 第一种方法有效,而不是第二种方法,它仍然让我在大型表(50k 行)上出现堆栈溢出。
      【解决方案3】:

      我最近有非常大的数据表,由于正在执行所有 DOM 操作,因此在进行更改时会占用 15 秒到 1 分钟的处理时间。除了 IE(在 IE8 中需要 5-10 秒),我在所有浏览器中都将它降低到

      我发现最大的速度提升是从 DOM 中删除我正在使用的父元素,对其执行更改,然后将其重新插入 DOM(在我的情况下为 tbody)。

      在这里你可以看到两行相关的代码,它们给我带来了巨大的性能提升(使用 Mootools,但可以移植到 jQuery)。

      update_table : function(rows) {
          var self = this;
          this.body = this.body.dispose();  //<------REMOVED HERE
          rows.each(function(row) {
              var active = row.retrieve('active');
              self.options.data_classes.each(function(hide, name) {
                  if (row.retrieve(name) == true && hide == true) {
                      active = false;
                  }
              });
              row.setStyle('display', (active ? '' : 'none'));
              row.store('active', active);
              row.inject(self.body);   //<--------CHANGES TO TBODY DONE HERE
          })
          this.body.inject(this.table);  //<-----RE-INSERTED HERE
          this.rows = rows;
          this.zebra();
          this.cells = this._update_cells();
          this.fireEvent('update');
      },
      

      【讨论】:

      • 好的,我可以看到其中的逻辑。但是,就我而言,我基本上是从 中删除一个表。您可能认为这不会花很长时间,但 内的表格包含 800 多个元素。鉴于这种情况,您认为您提出的解决方案仍然有效吗?
      • 我愿意。他们正在 HTML 5 中引入 DOM 片段来解决这个问题。我认为,如果您尝试拉出 、更新它并将其放回原处,您会看到巨大的性能提升。做起来也很简单,我用两行代码进行了更改。如果您安装了 Firebug,您可以使用“控制台”选项卡下的“配置文件”按钮来查看您的性能在哪里受到影响。
      【解决方案4】:

      您必须一次重新填充所有内容,还是可以通过 setTimeout() 上的块来完成?我意识到这可能需要更长的时间,但对于用户来说,看到正在发生的事情而不是明显的锁定是值得的。

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签