Ben Pearce
Ben Pearce

Reputation: 7094

What is the fastest way to dynamically generate a list in jQuery Mobile

I am creating a jQuery mobile app where UI events generate lists on the fly. So the faster I can make these lists come up the more responsive my UI will appear. I've outlined a few approaches below. My hope is that people with expertise on web performance can either tell me which approach they think is best or suggest an entirely new approach.

Approach #1 "Programaticaly Generate

  • selectors from an array of list element objects"

    $.each(array, function(index, value){
    var listElement = "$(<li></li>)";
    listElement.text(array.elementName);
    //Do some other stuff to listElement
    $("#displayedList").append(listElement);
    //append to Displayed List
    });
    

    Approach #2 "Clone

  • elements from dom object from an array of list element objects"

    $.each(array, function(index, value){
    var listElement = $("#listElementTemplate").clone();
    //Cloned list element from already loaded dom element
    listElement.text(array.elementName);
    //Do some other stuff to listElement
    $("#displayedList").append(listElement);
    //append to Displayed List
    });
    

    Approach #3 "Display already loaded list in an iframe"

    $("#displayedListWrapper").find("iframe").src("#loadedList");
    

    Upvotes: 1

    Views: 559

  • Answers (1)

    krishwader
    krishwader

    Reputation: 11381

    Here's a jsPerf I made for your scenarios : http://jsperf.com/dynamic-li

    Setup

    Here's the sample JSON I used for this :

    [
        "Sweet Child 'O Mine",
        "Summer of '69",
        "Smoke in the Water",
        "Enter Sandman",
        "I thought I've seen everything",
        "Never Hear Surf Music Again",
        "The Canyon",
        "Liberation Begins",
        "Touch of the Sun",
        "Lovely Day",
        "Ca Plane Pour Moi",
        "Liberation In A Dream",
        "If You Love Me (Really Love Me)",
        "Acid Darbari",
        "R.I.P.",
        "Festival",
        "If I Rise",
        "Liberation",
        "Nocturne No. 2 in E flat"
    ]
    

    And the test methods used are :

       //Scenario #1 : Programmatically generate li elements
       function makeLiProgrammatically() {
           $.each(songs, function (i, song) {
               var listElement = $("<li></li>");
               listElement.text(song);
               $list.append(listElement);
           });
           $list.listview("refresh");
       }
       //Scenario #2 : Clone DOM <li> element
       function cloneDOMLi() {
           $.each(songs, function (i, song) {
               var listElement = $("#listElementTemplate").clone();
               //Cloned list element from already loaded dom element
               listElement.text(song);
               //Do some other stuff to listElement
               $list.append(listElement);
               //append to Displayed List
           });
    
           $list.listview("refresh");
       }
       //Extra scenario - replacing each loop with for loop in scenario #1
       function makeLiProgrammaticallyForLoop() {
           for (; i < songs.length; i++) {
               var listElement = $("<li></li>");
               listElement.text(songs[i]);
               $list.append(listElement);
           };
           $list.listview("refresh");
       }
    

    The last scenario is my addition, just to check if for is better than each in this scenario. And the results are.. drumroll

    Results

    jsPerf result

    It looks like adding <li> programmatically, with for loop was the fastest! The reason, as Omar mentioned, is simple. You're creating an element in memory, so it doesnt consume that much of memory. Whereas, in your scenario #2, you were going to the DOM, searching for the li element (that too, repeatedly), which slowed it up. - See EDIT

    Hope this clears things up!

    PS Dont mind the screwed up formatting in jsPerf, I think jQM screwed it up when I added it to the scripts.

    EDIT

    As Mathias pointed out, cloning a DOM object is the fastest! This is what I changed in scenario #2 :

    //Scenario #2 : Clone DOM <li> element
           function cloneDOMLi() {
               var listElement = $("#listElementTemplate"); //pre cached the li so that it can be used again and again
               $.each(songs, function (i, song) {
                   $list.append(listElement.clone().text(song));
               });
    
               $list.listview("refresh");
           }
    

    And added an extra scenario :

     function cloneDOMLiForLoop() {
       for(;i<songs.length; i++){
           //Cloned list element from already loaded dom element
           $listElement.clone().text(songs[i]);
           //Do some other stuff to listElement
           $list.append($listElement);
           //append to Displayed List
         };
    }
    

    It looks like caching the DOM li did the trick! And as mentioned in the previous (wrong) observation, for is faster than each in this case as well. Results :

    revised jsPerf

    EDIT 1 I added one more test which creates <li></li> only once, and clones it in the loop. And of course using for loop. Here's the code :

    function makeLiProgrammaticallyOnceForLoop() {
         var li = $("<li></li>");
         for(;i<songs.length; i++){
           $list.append(li.clone().text(songs[i]));
         };
         $list.listview("refresh");
    }
    

    And here are the results :

    enter image description here

    Looks like programmatically creating li and reusing it through clone is also fast. So these would go without saying :

    1. You could either create an element dynamically, or get it from the DOM
    2. Pre-cache your element and re-use by clone.
    3. Use for instead of each if you want good performance.

      Important I didnt mention i-frame approach in tests because for mobile phones, especially the ones running Android OS 2.3.7, there is a clunky implementation of i-frames in the native browser, its always good to avoid them, even though that might be the fastest one of your scenarios.

    Upvotes: 1

    Related Questions