MOCKSTACKS
EN
Questions And Answers

More Tutorials









Jquery-Effcient-consecutive-append-usage


HTML

<table id='my-table' width='960' height='500'></table>

JS

var data = [
 { type: "Name", content: "John Doe" },
 { type: "Birthdate", content: "01/01/1970" },
 { type: "Salary", content: "$40,000,000" },
 // ...300 more rows...
 { type: "Favorite Flavour", content: "Sour" }
];

Appending inside a loop
You just received a big array of data. Now it's time to loop through and render it on the page.
Your first thought may be to do something like this:

var i; // <- the current item number
var count = data.length; // <- the total
var row; // <- for holding a reference to our row object
// Loop over the array
for ( i = 0; i < count; ++i ) {
 row = data[ i ];
 // Put the whole row into your table
 $('#my-table').append(
 $('<tr></tr>').append(
 $('<td></td>').html(row.type),
 $('<td></td>').html(row.content)
 )
 );
}

This is perfectly valid and will render exactly what you'd expect, but...
DO NOT do this.
Remember those 300+ rows of data?

Each one will force the browser to re-calculate every element's width, height and positioning values, along with any other styles - unless they are separated by a layout boundary, which unfortunately for this example (as they are descendants of a element), they cannot.

At small amounts and few columns, this performance penalty will certainly be negligible. But we want every millisecond to count.

Better options

1. Add to a separate array, append after loop completes

/**
 * Repeated DOM traversal (following the tree of elements down until you reach
 * what you're looking for - like our <table>) should also be avoided wherever possible.
 */
// Keep the table cached in a variable then use it until you think it's been removed
var $myTable = $('#my-table');
// To hold our new <tr> jQuery objects
var rowElements = [];
var count = data.length;
var i;
var row;
// Loop over the array
for ( i = 0; i < count; ++i ) {
 rowElements.push(
 $('<tr></tr>').append(
 $('<td></td>').html(row.type),
 $('<td></td>').html(row.content)
 )
 );
}
// Finally, insert ALL rows at once
$myTable.append(rowElements);

Out of these options, this one relies on jQuery the most.

2. Using modern Array.* methods

var $myTable = $('#my-table');
// Looping with the .map() method
// - This will give us a brand new array based on the result of our callback function
var rowElements = data.map(function ( row ) {
 // Create a row
 var $row = $('<tr></tr>');
 // Create the columns
 var $type = $('<td></td>').html(row.type);
 var $content = $('<td></td>').html(row.content);
 // Add the columns to the row
 $row.append($type, $content);
 
 // Add to the newly-generated array
 return $row;
});
// Finally, put ALL of the rows into your table
$myTable.append(rowElements);

Functionally equivalent to the one before it, only easier to read.

3. Using strings of HTML (instead of jQuery built-in methods)

// ...
var rowElements = data.map(function ( row ) {
 var rowHTML = '<tr><td>';
 rowHTML += row.type;
 rowHTML += '</td><td>';
 rowHTML += row.content;
 rowHTML += '</td></tr>';
 return rowHTML;
});
// Using .join('') here combines all the separate strings into one
$myTable.append(rowElements.join(''));

Perfectly valid but again, not recommended. This forces jQuery to parse a very large amount of text at once and is not necessary. jQuery is very good at what it does when used correctly.

4. Manually create elements, append to document fragment

var $myTable = $(document.getElementById('my-table'));
/**
 * Create a document fragment to hold our columns
 * - after appending this to each row, it empties itself
 * so we can re-use it in the next iteration.
 */
var colFragment = document.createDocumentFragment();
/**
 * Loop over the array using .reduce() this time. 
 * We get a nice, tidy output without any side-effects.
 * - In this example, the result will be a
 * document fragment holding all the <tr> elements.
 */
var rowFragment = data.reduce(function ( fragment, row ) {
 // Create a row
 var rowEl = document.createElement('tr');
 // Create the columns and the inner text nodes
 var typeEl = document.createElement('td');
 var typeText = document.createTextNode(row.type);
 typeEl.appendChild(typeText);
 var contentEl = document.createElement('td');
 var contentText = document.createTextNode(row.content);
 contentEl.appendChild(contentText);
 // Add the columns to the column fragment
 // - this would be useful if columns were iterated over separately
 // but in this example it's just for show and tell.
 colFragment.appendChild(typeEl);
 colFragment.appendChild(contentEl);

 rowEl.appendChild(colFragment);
 // Add rowEl to fragment - this acts as a temporary buffer to
 // accumulate multiple DOM nodes before bulk insertion
 fragment.appendChild(rowEl);
 return fragment;
}, document.createDocumentFragment());
// Now dump the whole fragment into your table
$myTable.append(rowFragment);


Conclusion

In this page (written and validated by ) you learned about Jquery Effcient consecutive .append() usage . What's Next? If you are interested in completing Jquery tutorial, your next topic will be learning about: Jquery append.



Incorrect info or code snippet? We take very seriously the accuracy of the information provided on our website. We also make sure to test all snippets and examples provided for each section. If you find any incorrect information, please send us an email about the issue: mockstacks@gmail.com.


Share On:


Mockstacks was launched to help beginners learn programming languages; the site is optimized with no Ads as, Ads might slow down the performance. We also don't track any personal information; we also don't collect any kind of data unless the user provided us a corrected information. Almost all examples have been tested. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. By using Mockstacks.com, you agree to have read and accepted our terms of use, cookies and privacy policy.