2016-01-28 5 views
0

Мне нужно создать сценарий потока, который вставляет 1000 элементов в секунду в разных столбцах, когда количество достигает 30 элементов на столбец, я удаляю их.Низкая производительность при вставке большого количества динамических элементов DOM

Я заметил, что могу использовать CSS для вставки моих данных, поскольку количество элементов DOM замедляется, если я скажу 100 столбцов и 50 строк в каждом; и весь процесс становится изменчивым.

Я создаю элементы и сохраняю их в массиве, чтобы улучшить производительность.

Как выполнить эту задачу с лучшей производительностью в чистом 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> 
+0

Я собирался предложить использовать DocumentFragment ... но я заблудился, пытаясь увидеть, если это будет вообще выгодно –

+0

насчет вместо того, один таймер, чтобы каждый столбец имел свой собственный таймер? Будет ли это работать лучше или хуже? – HelpNeeder

ответ

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); 
} 

+0

Наличие собственного счетчика должно принести определенные результаты. Хорошая точка зрения. Благодарю. – HelpNeeder

1

Вы можете попробовать переключиться из setInterval для requestAnimationFrame, а затем поместить содержимое своего создания функции в верхней части функции часов. Вызов функции довольно дорогой.

Живой пример: 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() { 

} 
+0

Ваш код сгенерировал еще 1000 строк в каждом вызове функции. Это определенно не поможет производительности. Также, какова польза от функции кадра запроса? Я никогда не использовал его. – HelpNeeder

+0

Прошу прощения, я думал, что целью было создать больше строк в секунду. RequestAnimationFrame обычно быстрее, чем setInterval. Я собирался опубликовать пример jsperf, но у меня были проблемы с сайтом, когда я его попробовал. Я сделаю еще один снимок позже. –

+0

Я должен также принять к сведению это. никогда не использовал его раньше. Благодарю. – Casey