Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
document.createElement() vs. document.createDocumentFragment()
(version: 0)
Comparing performance of:
addRowsByElement() vs addRowsByFragment()
Created:
2 years ago
by:
Guest
Jump to the latest result
HTML Preparation code:
<h3 id="title">document.createElement() vs. document.createDocumentFragment()</h3> <p> If you are writing an application/page that does a large amount of DOM manipulation, using document.createDocumentFragment() can dramatically increase performance of your application/page. Per David Walsh, a senior web developer with Mozilla: <blockquote> DocumentFragments allow developers to place child elements onto an arbitrary node-like parent, allowing for node-like interactions without a true root node. Doing so allows developers to produce structure without doing so within the visible DOM -- an increase of speed is the true advantage. <br /><br /> DOM injections and modifications are taxing, so the fewer the interactions the better; that's where the DocumentFragment comes in... Using DocumentFragments is faster than repeated single DOM node injection and allows developers to perform DOM node operations (like adding events) on new elements instead of mass-injection via innerHTML. </blockquote> Conceptually, both work in a similar fashion, but as Walsh points out, createDocumentFragment is more like a virtual DOM, which you can modify without the cost of restyling/redrawing a page. You do all of the same manipulation as with createElement, but you just append everything to the DOM in one fell swoop, as opposed to many appendChild calls. </p> <h4>Examples</h4> <p> Because the end result will look the same, we'll simply take a look at code examples of each method. In this case, let's prentend we need to add four rows to an existing table. </p> <table> <caption>purchase order #123456</caption> <thead> <tr> <th>Items</th> <th>Unit Cost</th> <th>Quantity</th> <th>Total</th> </tr> </thead> <tbody id="poList"> <tr> <td>widget A</td> <td>$20.00</td> <td>3</td> <td>$60.00</td> </tr> <tr> <td>widget B</td> <td>$15.00</td> <td>4</td> <td>$60.00</td> </tr> </tbody> </table> <p> See the code in the JS tab. The first function, addRowsByElement(), adds the rows using createElement. You cannot see it until the elements are finally added to the list (poList element) in the last line of the function, but this function is manipulating the DOM behind the scenes. Now, for this amount DOM manipulation, there will likely not be a lot of calculation savings, but when scaling this up the function becomes inefficient. </p> <p> The next function looks nearly identical; however, we are using createDocumentFragment() to handle all of the manipulation through a virtual DOM. So, we create the row and cells, just as in the previous function, but we append them to the fragment. Once we are done with the loop, we append the fragment to the DOM, which is more efficient. </p> <p> So, the general rule of thumb is: if you are just doing a few DOM manipulations, createElement() is fine; however, if you do a lot of DOM manipulation, or if the application/page will be heavily used, it makes more sense to use createDocumentFragment(). </p>
Script Preparation code:
function addRowsByElement () { // let's create four rows... for ( var looper = 1; looper <= 4; looper++ ) { // create the row element var tempRow = document.createElement("tr"); // create the cell (table data) elements var itemName = document.createElement("td"); var unitCost = document.createElement("td"); var itemQuantity = document.createElement("td"); var totalCost = document.createElement("td"); // add the cells to the row tempRow.appendChild(itemName); tempRow.appendChild(unitCost); tempRow.appendChild(itemQuantity); tempRow.appendChild(totalCost); // add the values to the cells itemName.appendChild(document.createTextNode("item " + looper)); unitCost.appendChild(document.createTextNode("$" + looper + "0.00")); itemQuantity.appendChild(document.createTextNode(looper)); totalCost.appendChild(document.createTextNode("$" + (looper * 10 * looper) + ".00")); // finally, added the row element to the poList element document.getElementById("poList").appendChild(tempRow); } } function addRowsByFragment () { // first, create the fragment var thisFragment = document.createDocumentFragment(); // let's create four rows... for ( var looper = 1; looper <= 4; looper++ ) { // create the row element var tempRow = document.createElement("tr"); // create the cell (table data) elements var itemName = document.createElement("td"); var unitCost = document.createElement("td"); var itemQuantity = document.createElement("td"); var totalCost = document.createElement("td"); // add the cells to the row tempRow.appendChild(itemName); tempRow.appendChild(unitCost); tempRow.appendChild(itemQuantity); tempRow.appendChild(totalCost); // add the values to the cells itemName.appendChild(document.createTextNode("part " + looper)); unitCost.appendChild(document.createTextNode("$" + looper + "0.00")); itemQuantity.appendChild(document.createTextNode(looper)); totalCost.appendChild(document.createTextNode("$" + (looper * 10 * looper) + ".00")); // finally, added the row element to the poList element thisFragment.appendChild(tempRow); } // finally, add the fragment to the DOM document.getElementById("poList").appendChild(thisFragment); }
Tests:
addRowsByElement()
addRowsByElement();
addRowsByFragment()
addRowsByFragment();
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (2)
Previous results
Fork
Test case name
Result
addRowsByElement()
addRowsByFragment()
Fastest:
N/A
Slowest:
N/A
Latest run results:
Run details:
(Test run date:
2 years ago
)
User agent:
Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0
Browser/OS:
Firefox 115 on Windows 8.1
View result in a separate tab
Embed
Embed Benchmark Result
Test name
Executions per second
addRowsByElement()
20385.2 Ops/sec
addRowsByFragment()
17752.5 Ops/sec
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
Based on the provided information, I'll attempt to provide an answer: The comparison between `createElement()` and `createDocumentFragment()` appears to be focused on their respective approaches to DOM manipulation. ** createElement() ** * Pros: + Easy to use and understand + Can be sufficient for small-scale DOM manipulations * Cons: + Inefficient for large-scale or frequent DOM updates, as it involves multiple appendChild calls, which can lead to unnecessary reflows and repaints. + May cause browser overhead due to the repeated DOM node creation and manipulation. ** createDocumentFragment() ** * Pros: + More efficient for large-scale or frequent DOM updates, as it allows for batched operations on a virtual DOM fragment, reducing the number of DOM node creations and manipulations. + Can lead to better performance and reduced browser overhead due to its optimized handling of DOM fragments. In conclusion, if you're working with small-scale DOM manipulations, `createElement()` might be sufficient. However, when dealing with larger or more complex DOM updates, `createDocumentFragment()` is likely a better choice, as it can provide significant performance benefits by reducing the number of DOM node creations and manipulations. Please note that this answer assumes the provided code examples and benchmark results are representative of the actual performance characteristics of these approaches.
Related benchmarks:
Dynamic Create of Table: insertRow() vs appending HTML
Add rows to Table: insertRow() vs appending innerHTML vs insertAdjacentHTML
Add rows to Table: insertRow() vs insertAdjacentHTML
JS: append vs prepend vs insertBefore vs appendChild vs insertAdjacentElement in a populated table
Comments
Confirm delete:
Do you really want to delete benchmark?