'Best way to create large static DOM elements in JavaScript?
I have many elements that one of my JS widgets needs to create and add to the DOM often. They never change.
So one option would be to store the HTML itself as a string in JS and use JQuery to create the elements from the string, then append it to the document:
var elements = "<div><table><tr><td>1</td><td>2</td></tr></table></div>";
function create() {
return $(elements);
}
$("body").append(create());
Another option is to write a function that will use document.createElement("div"), or $("<div>") many times to build the elements, append them to each other where needed, then append to the document:
function create() {
return $("<div>").append($("<table>")......
}
$("body").append(create());
In the first case, I have a big JS string that is actually HTML. In the second case, I have an unwieldy piece of JS that actually represents HTML.
Are there (dis)advantages to one or the other? Is there a better solution I'm not thinking of?
Solution 1:[1]
Detailed analysis of 3 commons ways of creating DOM in JS and the best approach.
I will provide 3 ways to create large DOM and their pros and cons, and of-course the most optimized way for large DOM creation and why. Bottom line is while creating DOM in js, native JS and DOM methods are your friend, don't use Jquery unless there is no other way(which is unlikely).
Test Data for comparison: Created 400 rows with 5 columns and appended to DOM. testData is list of objects that you get from backend in json form to create table.
Attached Execution time test result snapshot for different browsers
HTML
<div id="employeeListContainer1"></div>
<table id="employeeList2">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Title</th>
<th>ID</th>
<th>Department</th>
</tr>
</thead>
</table>
1st way : String Concatenation (Most Optimized way in terms of performance across browsers)
var tableElementContainer1 = document.getElementById("employeeListContainer1");
var temptableHolder = '<table><thead><tr><th>First Name</th><th>Last Name</th><th>Title</th><th>ID</th><th>Department</th></tr></thead><tbody>';
for(var i=0,len=testData.length; i<len; i++){
temptableHolder += '<tr><td>' + testData[i].firstName + '</td><td>' + testData[i].lastName + '</td><td>' + testData[i].title
+ '</td><td>' + testData[i].id + '</td><td>' + testData[i].department + '</td></tr>';
}
temptableHolder += '</tbody></table>';
tableElementContainer1.innerHTML = temptableHolder ;
Pros:
- Fastest execution time across Firefox/Chrome/IE/Safari (3 to 5 millisec across browsers). Measured via both performance.now() and console.time() APIs.
Cons:
- When number of columns are more and you need to set lot of attributes then working with strings can get little difficult and less main tenable.
2nd way: Native Js document.createElement()(This is 2nd best approach in terms of performance across browsers)
var tableBody = document.createElement('tbody');
var tableElement2 = document.getElementById("employeeList2");
for(var i=0,len=testData.length; i<len; i++){
tableRow = document.createElement("tr");
for(var k in testData[i]){
rowCell = document.createElement("td");
rowCell.appendChild(document.createTextNode(testData[i][k]));
tableRow.appendChild(rowCell);
}
tableBody.appendChild(tableRow);
}
tableElement2.appendChild(tableBody);
Pros:
- 2nd fastest execution time across Firefox/Chrome/Safari (5 to 12 millisec across browsers). Measured via both performance.now() and console.time() APIs.
- More main tenable than 1st Approach
Cons:
- Execution time is more in IE browsers, 90+ millsec
3rd Way: Using Jquery to create DOM (My advise is don't use it)
var tableBody = $('<tbody></tbody>');
var tableElement2 = document.getElementById("employeeList2");
for(var i=0,len=testData.length; i<len; i++){
tableRow = $("<tr></tr>");
for(var k in testData[i]){
rowCell = $("<td></td>");
rowCell.append(testData[i][k]);
tableRow.append(rowCell);
}
tableBody.append(tableRow);
}
tableElement2.append(tableBody);
Pros:
- Easy to add attributes/class/styles on elements and is easy to read and main tenable.
Cons:
- Worst execution time across all browsers (220 ms to 330 ms), slowest numbers are in IE
Solution 2:[2]
You can try doing an AJAX fetch of the static HTML block instead of storing it in the page itself. It allows you to be more flexible with what kind of block you want to insert in the future as well.
Alternatively (this is just a random idea which and not very well fleshed out), you can store the "structure" as JSON data and then dynamically parse it. Possibly something like {"div": {"div": {"span": "Text here"}}} for <div><div><span>Text here</span></div></div>. I'd still go with AJAX though. :)
Solution 3:[3]
There is another option, you can put the HTML right into the current html inside of hidden div like this:
<div id="hiddenContainer" style="display:none;">
<div><table><tr><td>1</td><td>2</td></tr></table></div>
</div>
And then in jquery, you can read it:
var elements = $("#hiddenContainer").html()
Solution 4:[4]
If you are looking for performance I would stick with the first version because in the second one everytime you are calling $('<div>') or $('<table>') you are creating a new jQuery Object and then call .append() which also another method call you do.
I would go with the first one.
Solution 5:[5]
Question was asked long long time ago. For modern day browsers using innerHtml property on the element is the most efficient way.
// Either create a new element or select an existing one:
const el = document.querySelector('#app');
el.innerHTML = `
<ul>
<li>Lorem ipsum dolor sit amet.</li>
<li>Adipisci perspiciatis blanditiis recusandae praesentium!</li>
<li>Libero, culpa similique. Laborum, tempore!</li>
<li>Nobis ab tempora laboriosam laborum!</li>
<li>Distinctio, a? Maiores, pariatur nihil.</li>
<li>Ab vitae quibusdam tempore rem?</li>
<li>Delectus veritatis exercitationem rem ipsam.</li>
<li>Eveniet praesentium quasi provident dicta!</li>
<li>Quae quis consequuntur perspiciatis omnis.</li>
<li>Delectus similique doloribus consequatur quidem!</li>
</ul>
`;
Browser will create the elements. It is faster and cleaner than creating elements individually through iteration. You can add properties, events, etc.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | AymDev |
| Solution 2 | seeming.amusing |
| Solution 3 | |
| Solution 4 | mas-designs |
| Solution 5 | snnsnn |
