2014年5月20日火曜日

[jQuery]大量の要素を高速に追加する方法

jQueryで大量の要素を動的に追加するときに最もパフォーマンスが高い方法を調べてみました。

Test用コード
<button id="btn0">clear</button><br>
<button id="btn1">$("<div ...") and append() every time</button><br>
<button id="btn2">clone() and append() every time</button><br>
<button id="btn3">clone() and append() at the end</button><br>
<button id="btn4">html() at the end</button><br>
<button id="btn5">innerHTML =... at the end</button><br>

<div id="container"></div>
<div id="template" style="background-color:blue">template</div>

<script type="text/javascript" src="jquery-2.1.0.min.js" charset="UTF-8"></script>
<script type="text/javascript">
  var container = $("#container");
  var template = $("#template");
  
  var label;

  $("#btn0").click(function() {
    container.empty();
  });

  // Slowest!
  $("#btn1").click(function() {
    label = $(this).text();
    console.time(label);
    for (i = 0; i < 1000; i++) {
      var o = $('<div id="template" style="background-color:blue">' + i + '</div>');
      container.append(o);
    }
    console.timeEnd(label);
  });

  // Slow.
  $("#btn2").click(function() {
    label = $(this).text();
    console.time(label);
    for (i = 0; i < 1000; i++) {
      var o = template.clone().attr("id", null).text(i);
      container.append(o);
    }
    console.timeEnd(label);
  });

  // 
  $("#btn3").click(function() {
    label = $(this).text();
    console.time(label);
    var arr = [];
    for (i = 0; i < 1000; i++) {
      var o = template.clone().attr("id", null).text(i);
      arr.push(o);
    }
    container.append(arr);
    console.timeEnd(label);
  });

  // Fastest!
  $("#btn4").click(function() {
    label = $(this).text();
    console.time(label);
    var html = "";
    for (i = 0; i < 1000; i++) {
      html += '<div style="background-color:blue">' + i + '</div>';
    }
    container.html(html);
    console.timeEnd(label);
  });

  // Fast
  $("#btn5").click(function() {
    label = $(this).text();
    console.time(label);
    var html = "";
    for (i = 0; i < 1000; i++) {
      html += '<div style="background-color:blue">' + i + '</div>';
    }
    container[0].innerHTML = html;
    console.timeEnd(label);
  });
</script>

Log:
$("<div ...") and append() every time: 125.766ms
clone() and append() every time: 109.372ms
clone() and append() at the end: 63.207ms
html() at the end: 10.185ms
innerHTML =... at the end: 16.094ms

結論

ループの中で html += ... して、最後にループの外で container.html(html) する方法が最速でした。
また、$(...)でjQueryオブジェクトを生成するよりも、できるだけtemplateを作っておいてそれをclone()する方が速そうです。
とにかく、ループの中での append() や innerHTML へのセットだけは避けるた方がいいみたいですね。

0 件のコメント:

コメントを投稿