【问题标题】:Low performance when inserting large amount of dynamic DOM elements插入大量动态 DOM 元素时性能低下
【发布时间】:2016-05-05 07:02:40
【问题描述】:

我需要创建一个流脚本,每秒在不同列中插入 1000 个元素,当数量达到每列 30 个元素时,我将删除它们。

我注意到我可以使用 CSS 插入我的数据,当我假设 100 列和 50 行时,DOM 元素的绝对数量会减慢;整个过程变得波涛汹涌。

我正在创建元素并存储在数组中以提高性能。

如何在纯 JavaScript 中以更好的性能执行此任务?

https://jsfiddle.net/r7qpmd4o/4/

<script>
    var elems = [],
            buffer = 1000,
        temp_row,
        temp_col,
        temp_var;

     // run
     create();
     clock();

    function clock() {
        setInterval(function() {
        for(var i = 0; i < 10; i++) {
            temp_col = document.getElementById('col' + i);

          temp_row = pop();

             if(temp_col.firstChild) {
                temp_col.insertBefore(temp_row, temp_col.firstChild);
            }
            else {
                temp_col.appendChild(temp_row);
            }

            if(temp_col.childNodes.length > 30) {
                temp_col.removeChild(temp_col.childNodes[30]);
            }
        }
      }, 1);
    }

    function pop() {
        if(elems.length < 1) {
            create();
      }

        temp_var = elems[elems.length -1];
      elems.pop();

      return temp_var;
    }

    function create() {
        for(var i = 0; i < buffer; i++) {
        temp_row = document.createElement('div');
        temp_row.className = 'a';

        elems.push(temp_row);
      }

      console.log('Elems created: ' + buffer);
    }
</script>

【问题讨论】:

  • 我打算建议使用 documentFragment ...但我迷路了,试图看看这是否有好处
  • 不使用一个计时器,而是让每一列都有自己的计时器怎么样?效果会更好还是更差?

标签: javascript html performance dom dynamic


【解决方案1】:
<script>
var elems = [],
        buffer = 1000,
    temp_row,
    temp_col,
    temp_var;

 // run
 create();
 clock();
 var nodeCOunter = 0; //counts what node until 30 hits
function clock() {
    setInterval(function() {
    for(var i = 0; i < 10; i++) {
        temp_col = document.getElementById('col' + i);

      temp_row = pop();

         if(temp_col.firstChild) {
            temp_col.insertBefore(temp_row, temp_col.firstChild);
        }
        else {
            temp_col.appendChild(temp_row);
        }

        if(nodeCounter == 30){
           temp_col.removeChild(temp_col.childNodes[30]);
           nodeCounter = 0; //reset
        }
          else
        {
           nodeCounter += 1; 

    }
  }, 1);
}

function pop() {
    if(elems.length < 1) {
        create();
  }

    temp_var = elems[elems.length -1];
  elems.pop();

  return temp_var;
}

function create() {
    for(var i = 0; i < buffer; i++) {
    temp_row = document.createElement('div');
    temp_row.className = 'a';

    elems.push(temp_row);
  }

  console.log('Elems created: ' + buffer);
}

【讨论】:

  • 拥有自己的计数器应该会带来一些结果。好点子。谢谢。
【解决方案2】:

您可以尝试为 requestAnimationFrame 切换 setInterval,然后将 create 函数的内容放在时钟函数的顶部。函数调用非常昂贵。

实时示例:http://codepen.io/larryjoelane/pen/GodmXE

JavaScript:

var elems = [],
        buffer = 1000,
    temp_row,
    temp_col,
    temp_var;

 // run
 //create();
 clock();

function clock() {

  //formally part of the create
  //function
  for(var i = 0; i < buffer; i++) {
    temp_row = document.createElement('div');
    temp_row.className = 'a';

    elems.push(temp_row);
  }

  console.log('Elems created: ' + buffer);
  //end create function

    window.requestAnimationFrame(function() {
    for(var i = 0; i < 10; i++) {
        temp_col = document.getElementById('col' + i);

      temp_row = pop();

         if(temp_col.firstChild) {
            temp_col.insertBefore(temp_row, temp_col.firstChild);
        }
        else {
            temp_col.appendChild(temp_row);
        }

        if(temp_col.childNodes.length > 30) {
            temp_col.removeChild(temp_col.childNodes[30]);
        }
    }

    window.requestAnimationFrame(clock);
  });
}

function pop() {
    if(elems.length < 1) {
        create();
  }

    temp_var = elems[elems.length -1];
  elems.pop();

  return temp_var;
}

function create() {

}

【讨论】:

  • 您的代码在每次函数调用时多生成 1000 行。那肯定对性能没有帮助。另外,请求框架功能有什么好处?我从来没有用过。
  • 抱歉,我认为目标是每秒创建更多行。 requestAnimationFrame 通常比 setInterval 快。我打算发布一个 jsperf 示例,但是当我尝试它时,该站点出现了一些问题。我稍后再试一次。
  • 我也必须注意这一点。以前从未使用过它。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-09-18
  • 2017-12-05
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
  • 2015-12-14
  • 1970-01-01
  • 2012-03-17
相关资源
最近更新 更多