【问题标题】:jQuery append is taking too much time when repeated 500 times重复 500 次时,jQuery 追加花费了太多时间
【发布时间】:2020-07-24 08:32:07
【问题描述】:

我有这个代码

$.getJSON( "https://domain.ltd/parse_data.php", function( data_recieved ) {
  if (data_recieved.length) {   
    $.each(data_recieved, function(index, element) {
      $( ".items" ).append( '<span>' + element.name +  ' = ' + element.amount + '</span><br />' );
    });
  }
})

如您所见,它正在解析 json 并使用append 显示结果。 但是,如果响应中有 500 行数据,则最多可能需要 30 秒来追加所有 500 行。发生这种情况时,网站没有响应。

不仅如此,我的 CPU 使用率达到了 50%。

我做错了吗?也许有一种更有效的方法来解析这么多数据并使用 jQuery 动态显示它?

【问题讨论】:

  • @Jeto 我不确定我是否做对了。我怎么会提前知道行数?也许您可以在答案中详细说明一下?
  • 那个小提琴只是为了展示使用 jQuery 追加 500 行应该没有任何问题。所以不管是什么花费了这么多时间/处理能力,它可能不是它。
  • 为什么不将所有跨度连接到一个变量中,然后在循环外只调用一次.append()?...这样可以避免循环中的 DOM 遍历。
  • @Jeto 好吧,json 页面在不到一秒的时间内打开,然后 jQuery 最多需要 30 秒来解析它。在我的真实代码中有更多的 html 和数据点,也许这就是它没有简化版本那么快的原因。

标签: javascript jquery


【解决方案1】:

我相信这是一个更好的解决方案

$.getJSON( "https://domain.ltd/parse_data.php", function( data_recieved ) {
  if (data_recieved.length) {   
    var spns = '';
    $.each(data_recieved, function(index, element) {
spns+='<span>' + element.name +  ' = ' + element.amount + '</span><br />'; 
    });
        $( ".items" ).append(spns); // or use .html();
  }
})

您的 DOM 树似乎很深,循环内的$( ".items" ) 变得越来越昂贵。

【讨论】:

  • 谢谢,这成功了。现在它的运行速度提高了 10 倍!
  • 更正:实际上它的工作速度要快数百倍。处理 900 行数据需要 30-40 毫秒。现在唯一需要时间的是在服务器端生成 json 脚本 :)
【解决方案2】:

您可以改进代码以提高性能。在代码的底部,我应用并描述了一些技巧。您可以在此页面的开发者控制台中查看使用时间。

// just for simulating your JSON
var dataRecieved = [];

for (var i = 0; i < 500; i++) {
  dataRecieved.push({ name: 'Element ' + i, amount: parseInt(Math.random() * i) });
}

// $.getJSON( "https://domain.ltd/parse_data.php", function( data_recieved ) {
// optimization start here
console.time('test');

// use a simple for loop and save the length of received data
var element, dataReceivedLength = dataRecieved.length;

// create a variable and append all html to it
var dataMarkup = '';

// if you want to do it on only one element, use the id as selector.
// save the object to a variable
var $items = $('#first-collection');

// check if $items exist
if ($items.length && dataReceivedLength) {
  for (var i = 0; i < dataReceivedLength; i++) {
    element = dataRecieved[i];
    dataMarkup += '<span>' + element.name + ' = ' + element.amount + '</span><br />';
  }
  
  // use html() instead of append() for performance reasons in this case
  $items.html(dataMarkup);
}

console.timeLog('test');
// });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<p id="first-collection" class="items"></p>

【讨论】:

  • 谢谢,但我选择了@techie_28 的答案,因为它没有for。在这里添加for 循环有什么好处吗?
  • @Steven 没问题。如您在这篇文章中所见,for 循环具有更好的性能:$.each() vs for() loop - and performance
  • 哦,哇。我会试试你的方法,然后报告我的结果。
  • 我决定不使用for 循环,因为当我使用时间日志功能检查当前解决方案时,它显示 900 行数据需要 30-40 毫秒。 json 文件编译现在是我脚本中最慢的部分(需要 1200 毫秒)。无论如何,感谢您提供如此精美的答案!
猜你喜欢
  • 2016-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 2020-07-23
  • 2013-07-11
  • 2014-01-13
  • 1970-01-01
相关资源
最近更新 更多