Treehouse

JavaScript DocumentFragment

By on  

One of the lessor known but incredibly useful gems within JavaScript is the DocumentFragment.  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.  Let me show you how DocumentFragments are used!

DocumentFragment Example

Let's start with a UL with which we'll inject LI's to:

<ul id="list"></ul>

DOM injections and modifications are taxing, so the fewer the interactions the better;  that's where the DocumentFragment comes in.  The first step is creating the DocumentFragment:

// Create the fragment
var frag = document.createDocumentFragment();

This DocumentFragment act like a pseudo-DOM node -- think of it as a virtual UL element, in this case.  Now it's time to add elements:

// Create numerous list items, add to fragment
for(var x = 0; x < 10; x++) {
	var li = document.createElement("li");
	li.innerHTML = "List item " + x;
	frag.appendChild(li);
}

Elements can be added to the DocumentFragment just as you could a normal DOM node.  Once the tree of DOM nodes is ready to hit the page, simply place the DocumentFragement into its parent (or other DOM placement functions):

// Mass-add the fragment nodes to the list
listNode.appendChild(frag);

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.  Keep DocumentFragment close by when performing lots of DOM operations -- it could speed up your app considerably!

ydkjs-3.png

Recent Features

  • Create Namespaced Classes with&nbsp;MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each...

  • An Interview with Eric&nbsp;Meyer

    I've always wanted to interview Eric Meyer. His early CSS books are a big reason this blog exists today and the reason why I'm a web developer. Eric gave me some time to hit the history of CSS,...

  • Introducing MooTools&nbsp;Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating:

Incredible Demos

  • Animated AJAX Record Deletion Using&nbsp;MooTools

    I'm a huge fan of WordPress' method of individual article deletion. You click the delete link, the menu item animates red, and the item disappears. Here's how to achieve that functionality with MooTools JavaScript. View Demo The PHP...

  • Using Opacity to Show Focus with&nbsp;jQuery

    A few days back I debuted a sweet article that made use of MooTools JavaScript and opacity to show focus on a specified element. Here's how to accomplish that feat using jQuery. View Demo The jQuery JavaScript $(document).ready(function() { //area 1 $('.fade-area-1').children().hover(function()...

  • MooTools Zebra Table&nbsp;Plugin

    I released my first MooTools class over a year ago. It was a really minimalistic approach to zebra tables and a great first class to write. I took some time to update and improve the class.

Discussion

  1. But test (http://jsperf.com/out-of-dom-vs-documentfragment/3) do not show “an increase of speed” …

  2. @sergey: Probably depends on your browser, I got about 5-6 % speed gain with your test. http://imgur.com/SjHWF

  3. David

    I ran that test too, and documentFragment was slower on all my browsers.

    I’m on a Mac… documentFragment was always slower on Firefox 16.0.2 and Safari 6.0.1 (3-4 tests); and mixed results (slower and faster) on Chrome 23.

    David

  4. I’ve created revision 7 to show the improvement of using docfragments. As for differences in creating a temp element using createElement vs createDocumentFragment,

    http://stackoverflow.com/questions/3397161/should-i-use-document-createdocumentfragment-or-document-createelement

    has some explanation.

  5. wouldn’t you want to just concat a string and append that once at the end?

    • Not if you want to add events or work with nodes DOM structure.

  6. fbender

    I “fixed” the jsperf test and had a better performance with Fx 17 Mac, Chrome did not show any significant performance difference between the two options.

    http://jsperf.com/out-of-dom-vs-documentfragment/10

    As long as some browsers profit from documentFragment, everybody should use it (well, at least if you do it correctly).

  7. I updated the speed test http://jsperf.com/out-of-dom-vs-documentfragment/11 by adding test without documentFragment, but still outside of DOM. documentFragment have a limitations and sometimes can not be used.

  8. seelts

    But why do so?
    I can do something like:


    var ul = document.createElement('ul');
    var li;
    for (...) {
    li = document.createElement('li');
    ul.appendChild(li);
    }

    smth.appendChild(ul);

    What is the difference?

    • That’s a good option, but sometimes the “main” element is already in the DOM… like your “ul”.

      So you wouldn’t be appending it into in a “phantom” element, but would be rendering it in the DOM itself. That may be a problem when we are thinking about reflow and thousands of elements.

  9. I too use the same method as @seelts, and am wondering the same about performance.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Use Code Editor