Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Run results for:
document.createElement() vs. document.createDocumentFragment()
Go to the benchmark
Embed
Embed Benchmark Result
Run details:
User agent:
Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0
Browser:
Firefox 115
Operating system:
Windows 8.1
Device Platform:
Desktop
Date tested:
2 years ago
Test name
Executions per second
addRowsByElement()
20385.2 Ops/sec
addRowsByFragment()
17752.5 Ops/sec
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();