Render Large jQuery Mobile Listview I am trying to write an efficient loop for rendering a jQuery Mobile listview.  Is this the most efficient loop?  I append elements 100 at a time to try and allow the user to see progress without blocking the UI.  This currently still needs work.

I also use a blend of html strings and jQuery DOM objects.  I'm not sure about the performance cost.

What are your thoughts? Assume items could be an array of 600/700 items.

/**
 * Renders the passed in list items into a JQM listview.
 * @param items {Array{Objects}} - An array of key/value objects
 */
function renderSourceItems(items)
{
    var content = $page.find(".content");

    if (!items)
    {
        content.html('&lt;p&gt;No Data Found&lt;/p&gt;');
    }
    else
    {
        var column,
            value,
            list,
            markup = "";

        column = _.keys(items[0])[0]; // The key is the database column

        content.empty();

        $('&lt;ul/&gt;', {
            "data-role" : "listview",
            "data-filter": "true",
            "data-theme" : "c"
        }).appendTo(content).listview();

        list = content.find('ul');

        for (var i = 0; i &lt; items.length; i++)
        {
            value = items[i][column];
            markup += '&lt;li&gt;&lt;a href="#apage" data-column="' + column  +'" data-value="' +  value +'"&gt;' + (value || "[No Value]") + '&lt;/a&gt;&lt;/li&gt;';

            if (i % 100 === 0)
            {
                list.append(markup).listview("refresh");
                markup = "";
            }
        }

        // refresh triggers the page to adjust its sizes,
        // otherwise long lists can force the footer navbar to the bottom of the list intead of the screen bottom.
        list.append(markup).listview("refresh");
    }
}
//elements that don 't change should be declared in a scope that doesn't 
 //get executed all the time to avoid redundant opearation
var content = $(".content", $page);

function renderSourceItems(items) {

  //JS normally pulls up variable declarations, even when declared
  //anywhere. To avoid readability issues, it's best you declare
  //them up here
  var column, list;

  //the "return early" or "blacklist" method returns if any anomalies
  //are found earlier in the code. That way, you don't use nested ifs
  if (!items) {
    content.html('&lt;p&gt; No Data Found &lt;/p&gt;');
    return;
  }

  //down here, it's assumed that items does exist and has content

  column = _.keys(items[0])[0];
  content.empty();

  //depending on the browser, DOM strings vs jQuery DOM vary in
  //performance. Since it varies, I'd rather improve readability
  //by using one of them that's more readable, where in my case
  //it's jQuery DOM building
  list = $('&lt;ul/&gt;', {
    "data-role": "listview",
    "data-filter": "true",
    "data-theme": "c"
  });


  //our recursive function using setTimeout to avoid freezing UI
  (function looper(i) {

    var value, item;

    if (!(i % 100)) {
      value = items[i][column];

      //each item gets built using our readable method
      //here we make a list item and append to it a link with
      //the given data
      item = $('&lt;li/&gt;').appendTo(list);
      $('&lt;a/&gt;', {
        'href': '#apage ',
        'data - column ': column,
        'data - value ': value
      }).text(value || ' [No Value]').appendTo(item);

    }

    setTimeout(function () {
      if (++i &lt; items.length) {
        //when not yet the last item, repeat
        looper(i);
      } else {
        //else we end

        //now you notice that we only append the list to the DOM down here
        //why not append it beforehand? The issue is DOM access - it's slow!
        //we take advantage of jQuery using DOM fragments, DOM elements that
        //are not in the DOM and just operate off-DOM. We only append
        //to the DOM after everything is completed, thus minimizing
        //DOM access from items.length times to just 1
        list.appendTo(content).listview("refresh");
      }
    }, 200);

    //start with index 0
  }(0));



}