Wednesday, August 14, 2013

How jQuery Mobile Eats PhoneGap Performance, See Experiment


As we know, jQuery Mobile renders a lot of HTML for a simple element/widget. For example, the below picture(from jQM demos) shows the HTML source code (right) of a simple list item(left).
However, to make such a list item, the html can be as simple as just: <li>Acura</li>(don’t know how? Leave a comment.)
But how will HTML elements affect the performance? Let’s take an experiment to see.
I wrote a simple page to test it. Open live demo for web browser(PC & Phone)
 <!DOCTYPE html>  
 <html xmlns="http://www.w3.org/1999/xhtml">  
   <head>  
     <meta charset="utf-8" />   
     <meta name="viewport" content="initial-scale=1, width=device-width" />  
     <title></title>  
     <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></script>  
   </head>  
 <body>  
   <p>  
     <input type="button" value="Render jQM" id="btnRenderjQM"/>  
     <input type="button" value="Render Custom" id="btnRenderCustom"/>  
   </p>  
   <p><b>Time: </b><span id="time">0</span></p>  
   <ul id="result" style="height: 200px; overflow: auto;"></ul>  
   <script language="javascript" type="text/javascript">  
     var time = null;  
     $(document).ready(function() {  
       var li1 = '<li data-corners="false" data-shadow="false" data-iconshadow="true" data-wrapperels="div" data-icon="arrow-r" data-iconpos="right" data-theme="c" class="ui-btn ui-btn-icon-right ui-li-has-arrow ui-li ui-first-child ui-btn-up-c">\  
               <div class="ui-btn-inner ui-li">\  
                 <div class="ui-btn-text"><a href="#" class="ui-link-inherit">Acura</a></div>\  
                 <span class="ui-icon ui-icon-arrow-r ui-icon-shadow">&nbsp;</span></div>\  
             </li>';  
       var li2 = '<li>Acura</li>';  
       $("#btnRenderjQM").click(function() {  
         var $ul = $("#result");  
         $ul.empty();  
         var html = '';  
         for (var i = 0; i < 1000; i++) {  
           html += li1;  
         }
         time = new Date();    
         $ul.html(html);  
         $("#time").html(new Date() - time);  
       });  
       $("#btnRenderCustom").click(function() {  
         var $ul = $("#result");  
         $ul.empty();  
         var html = '';  
         for (var i = 0; i < 1000; i++) {  
           html += li2;  
         }
         time = new Date();    
         $ul.html(html);  
         $("#time").html(new Date() - time);  
       });  
     });  
   </script>  
 </body>  
 </html>  
There are two buttons on the test page, one appends 1000 jQueryMobile list items to the list, while the other appends 1000 simple list items.
Let’s see some charts.
Test in firefox:

Test in google chome:

Test on Android Phone:
The charts mean: HTML elements eat performance. If we use simple HTML elements to render a page, it will save about 80% performance than using jQM. If it’s a small page, that would be OK using jQM, if it’s a complex page, I recommend you write the HTML elements by yourself.
The above test page can be viewed online here: live demo for web browser(PC &Phone).
Feel free to make comments or ask questions.

14 comments:

  1. I've never been a fan of using jQM inside a PhoneGap app. Certainly their list item adds a number of extra dom elements to show that right arrow button. Setting the data-icon="false" will get rid of the span element so that helps a bit. If you don't want to include jQuery and jQuery Mobile just to get a list element you can look at a CSS only approach like http://topcoat.io/topcoat/#list.

    As well if you are going to have a very large list you may want to look into infinite scrolling techniques where list items are added/removed from the dom as needed.

    ReplyDelete
    Replies
    1. Yes Simon, infinite scrolling would be a nice choice, but if the list item template is very big, the scrolling cannot go far. Since when it becomes a long list, the scrolling performance will be bad.

      Delete
  2. I guess the reason for this bloated DOM is that JQM supports many browsers so it doesn't use the features of modern browsers to reduce the DOM here. Best approach would be to write different HTML and CSS depending on the possibility of the browser used BUT this is very complicated and generates a huge code base...

    ReplyDelete
  3. I wrote yesterday, but my comment didn't appear.
    You should do a real test, with jquery mobile css and js included, and then append the 1000 simple li elements and use the listview("refresh") method, that is the method than creates all the extra html.

    ReplyDelete
    Replies
    1. This experiment only tests the time of rendering html elements. And I guess the result is very clear now.

      If css and js are included, jQM should uses much more time, since the css will be more complex than your custom one.

      Delete
  4. And about Sencha Touch + Phonegap? Same problem?

    ReplyDelete
  5. Sencha Touch reuses 20 list items. If you had 20 or 2000 it would look the same.

    ReplyDelete
  6. I can talk about PhoneGap and not Sencha Touch, I always follow PhoneGap because it is easy to use and reliable. You will do nothing but write code once, and within few minutes you will get mobile applications for all the major platforms within minutes!

    ReplyDelete
  7. You might be interested in JQM 1.4. Extra HTML elements are not added anymore (or at least no in the lists and other simple elements). I'm currently moving my application to this version and first results seem to be promising. JQM looks quite differently with new theme, but I guess its in accordance with new trends (more squares, less gradients).

    ReplyDelete
    Replies
    1. How do you organize your html/js files? All in one?

      Delete
  8. This comment has been removed by the author.

    ReplyDelete
  9. I had to abandon jQM for my PhoneGap app. The performance was very slow. jQM is not really intended for offline PhoneGap apps. Instead, it's aimed at web apps running on mobile devices via a normal web browser. Also, jQM's goal of working on so many different browsers (Meego, Tizen) is ridiculously broad. By catering to so many obsolete browsers with virtually no marketshare, jQM cannot be optimized to run well in PhoneGap.

    ReplyDelete