1

Using jQuery .append I write some html to form a 10,000px grid of 125px X 80px. Where the pixels are numbered first down then across. Now this works fine but is slow enough that there's noticeable lag loading the page compared to writing it straight in html. Is it possible to speed this up at all while still maintaining the pixel numbering?

My html is:

<div id="grid">
</div>

Javascript:

function createGrid() { 
var counter = 1;
var rowCounter = 1;
var divs = 10000;
$('<table width="625px"><tr>').appendTo('#grid');
for (var i = 1; i <= divs; i++) {
    if (i % 125 == 0 ){
        $('</ tr><tr>').appendTo('#grid');
        rowCounter++;
        counter = rowCounter;
    }   
    else
        $('<td id="pixel_' + counter + '" class="pixel"></td>').appendTo('#grid');
        counter =+ 80;
    }
$('</tr></table>').appendTo('#grid');   
}
Michael Irigoyen
  • 22,513
  • 17
  • 89
  • 131
baarkerlounger
  • 1,217
  • 8
  • 40
  • 57

3 Answers3

4

Your code won't work as you expect it to, because .append() creates complete DOM elements. $('<table width="625px"><tr>').appendTo('#grid') will automatically close both tags, and you'll have to append the next row to the table, and the cell to the row.

As it happens, it's inefficient to constantly append elements to the DOM anyway. Instead, build the table as a single string and write it out all at once. This is more efficient since you're only adding to the DOM one time.

function createGrid() {
    var counter = 1;
    var rowCounter = 1;
    var divs = 10000;
    var tstr = '<table width="625px"><tr>';
    for (var i = 1; i <= divs; i++) {
        if (i % 125 == 0) {
            tstr += '</ tr><tr>';
            rowCounter++;
            counter = rowCounter;
        } else
            tstr += '<td id="pixel_' + counter + '" class="pixel"></td>';
        counter = +80;
    }
    tstr += '</tr></table>';
    $('#grid').append(tstr);
}

http://jsfiddle.net/mblase75/zuCCx/

Community
  • 1
  • 1
Blazemonger
  • 90,923
  • 26
  • 142
  • 180
  • Thanks works great - I had assumed (wrongly) appendTo was just writing I didn't realise it created a new DOM element - will mark this solved as soon as the timer allows. – baarkerlounger May 23 '13 at 14:33
  • 2
    It's a common misunderstanding, one we all have at some point. We code in HTML tags, but the browser understands DOM elements, and part of being a JavaScript programmer is shifting your thinking about how a web page is built from one to the other. – Blazemonger May 23 '13 at 14:35
  • Thanks - I notice the html output from this does not show up when I click view source. Is that related to this in any way? – baarkerlounger May 23 '13 at 14:44
  • 1
    "view source" gets the original source from the server, not the rendered DOM after it's been manipulated. Use your browser's developer tools to view the DOM elements as the browser sees them. In Chrome, it's `View > Developer > Developer Tools` – Blazemonger May 23 '13 at 14:45
1
$('<table width="625px"><tr>')

is not the same as writing and appending an HTML string! jQuery will evaluate that <table><tr> string and create a DOMElement from it. I.e., with just this tiny bit of code, you have created a whole table in the DOM. The closing tags are auto-completed and the table is instantiated. From then on you need to work with it as a DOM object, not as a string to append to.

Your code is probably slow because you're creating tons of incomplete/autocompleted tiny DOM objects which are all somehow being bunched together, probably not even in the correct structure. Either manipulate DOM objects, which should be pretty fast, or construct a complete string and have it evaluated once.

deceze
  • 510,633
  • 85
  • 743
  • 889
0

One of the first steps towards improving performance would be generating the complete HTML and appending to the DOM in one step.

function createGrid() { 
   var counter = 1;
   var rowCounter = 1;
   var divs = 10000;
   var html = '<table width="625px"><tr>';
   for (var i = 1; i <= divs; i++) {
      if (i % 125 == 0 ){
         html  += '</ tr><tr>';
         rowCounter++;
         counter = rowCounter;
     }   
     else
        html += '<td id="pixel_' + counter + '" class="pixel"></td>';
        counter =+ 80;
    }
    html += '</tr></table>';
    $('#grid').html(html);
}
techfoobar
  • 65,616
  • 14
  • 114
  • 135