Web Performance Optimization Tip - jQuery + Document Fragments

Here's the setup... You have a REST API returning a JSON object filled with a bunch of data that you want to put into a list. It looks vaguely like this:

[{1234:{name:'bob'}},{5678:{name:'karen'}}]

 

Two names for brevity, but the list can be N length.

Let's say you want to put this into a simple list of names.

Here's the way I still see way too many devs doing it:

<html>
<body>
<ul class="names"></ul>

<script>
$(function(){
  var restResponse = [{1234:{name:'bob'}},{5678:{name:'karen'}}];

  $.each(restResponse,function(index,value){
       $('.names).append('<li>'+value.name+'</li>'); 
  }); 
});
</script>
</body>
</html>

 

It works.. and its not really THAT bad for two names.. but what if you had 100, or 1000? Especially if you are developing for mobile, you need to use this, or you're killing your performance over one fairly simple block of know-how.

That know-how is called document fragments. I'm not going to go in depth on what document fragments are, you can check out the post on the subject by John Resig here.

The short version is that they are DOM elements you can create in memory, that don't cause screen redraws when you manipulate them. The benefit: You can add LOTS of nodes to them in memory, write them to the screen, still keep them in memory, remove them from the screen, still keep them in memory, and manipulate them as some kind of awesome phantom DOM object. Seriously, document fragments are bad-ass, and if you want to be bad-ass, you need to know how to use them. Not only that, but jQuery makes it stupendously easy to work with them.

Let's go back to the example... What if we make some minor modifications?

<html>
<body>
<div class="names"></ul>

<script>
$(function(){
  var restResponse = [{1234:{name:'bob'}},{5678:{name:'karen'}}];
  var $ul = $('<ul>');
  $.each(restResponse,function(index,value){
       $ul.append('<li>'+value.name+'</li>'); 
  }); 
  $('.names').append($ul); // or you could do $ul.appendTo('.names') whatever makes you smile.
});
</script>
</body>
</html>

 

Do you see what I did there? Here it is in super slow-mo:

var $ul = $('<ul>');

 

Yes, that made a document fragment of an unordered list. That's all it took. You can also add attributes to it like this:

var $ul = $('<ul>',{id:'listOfNames'});

 

Then we loop through our JSON object and stick each list item into the fragment:

 $.each(restResponse,function(index,value){
       $ul.append('<li>'+value.name+'</li>'); 
  });

 

Then we stick it onto the screen.

$('.names').append($ul); // or you could do $ul.appendTo('.names') whatever makes you smile.

 

If you've been making this mistake, stop now and go refactor your code.