0

Here is what I am trying to do: In a phonegap android app, use jquery listview to create a UL dynamically from my static xml and show it.

To create a filterable listview, I used the code from w3schools.
Then I add elements dynamically from my XML using the following code in onload() method in HTML body:

function parseit() {
    alert("parseit");
    $.ajax({
    type: "GET",
    url: "catalog.xml",
    dataType: "xml",
    success: function(xml) {
        $(xml).find("Book").each(function(){
            var title = $(this).find('Name').text();
            console.log(title);
            var listItem = '<li> <a href="#">' +title + '</li>';
            $("#list").append(listItem).listview('refresh');
        });
    }
    });
}

my XML file's schema is like :

<Books>
   <Book>
      <Name> somename </Name>
      <Price> $1.00 </Price>
      <Details> asdfgh </Details>
   </Book>
   <Book> .....  1500 items of this kind...  </Book>
</Books>

Few issues I am facing :

  1. Listview does not show the newly added items immediately though I am calling refresh. I saw at few place about removing div Content etc. but I am not using it ( see code from link i gave). I have to click around, after a long time, for items to show up. Jquery listview is too slow. The # of list items I am adding is 1500-ish.

  2. Items added dont fall into sorted headers ( eg. items starting with 'A' dont go back to that section, instead a new 'A' section is created at the bottom

I chose listview of jquery since it is giving me free search functionality.

techtinkerer
  • 1,280
  • 2
  • 15
  • 26
  • you mean the console.log ? sure, do. Forgot to add, the parseit() function gets called with onload. – techtinkerer Mar 18 '14 at 19:12
  • so are you saying that you are loading 1500 items in the view ? – AlexCon Mar 18 '14 at 19:49
  • yes, my XML has 1500 items that I am adding using the parseit() function above. I removed the console.log statement. Still app is not responsive. – techtinkerer Mar 18 '14 at 19:58
  • For faster processing, prefer JSON than XML. It also reduces the bandwidth usage a lot. See [Why is everyone choosing JSON over XML for jQuery](http://stackoverflow.com/questions/1743532/why-is-everyone-choosing-json-over-xml-for-jquery) – Sen Jacob Mar 18 '14 at 20:57

2 Answers2

1

Alright let's discuss the problem. Based on my personal experience, you can't expect the browser to handle that many items specially in a mobile device. There are all sort of performance issues with js running in mobile browser and also DOM limitation. You have to follow these steps to figure out the root cause of the slow performance:

  1. Make a copy of your XML and trim it down to a something like 50 or 75 items

  2. Run it, and observe if you still see the same performance issue.

  3. If you still see the performance issue, then you gotta optimize your code

  4. If the performance issue is resolved, then you should figure out a way to parse on demand. For example: Parse the first few dozens, and as the user enters, search through the XML and parse on demand.

There is no way you can dynamically add 1500 items in a mobile using DOM and JS and expect a good performance. Once I created 600 div dynamically on a Desktop browser and it was super slow. It's because how DOM processes dynamic stuff, traversing the heirachy in order to place the item in the right place. You may think it's a simple process, but that whole traversing cost CPU and processing time. If there is a way to minimize the parsing and make it on demand, that would be great.

Read on Proxy Design Pattern, sometimes when you deal with huge data-set, you use proxies to make the user feel everything is loaded, but only a fraction of it is available while the rest is dummy waiting for on demand retrieval.

Hope my suggestion works for you.

http://en.wikipedia.org/wiki/Proxy_pattern

Try this version of jquery and it may help, it's for mobile devices: http://jquerymobile.com/

AlexCon
  • 1,127
  • 1
  • 13
  • 31
  • yes, I am using that - jquery-1.10.2.min.js, jquery.mobile-1.4.2.min.js, jquery.mobile-1.4.2.css in my project. – techtinkerer Mar 18 '14 at 19:06
  • yes, I agree with you that perf could be impacted due to large # of items. However, if i dont use JQuery but just add these items to a plain HTML and Javascript UL then it is doing fine with no issues. In this case, UI looks like just list of links ( book title and hyper link to book details). – techtinkerer Mar 18 '14 at 22:11
  • As you know, JQuery is a library that is written on top of the Javascript, that means there are a lot of codes being used under the hood in order to give you more functionalists with less amount of code, that enhances the productivity as a developer, but at the cost of less power to optimize the code. – AlexCon Mar 19 '14 at 00:50
  • For instance, Hibernate is an ORM tool that makes it very easy for Java developers to use traditional databases in an OOP manner, but it creates some low performance sql queries under the hood that sacrifice performance for ease of development. If you need good performance, you need to write your own function for that specific part, or learn more about in what other ways you can accomplish the same result with less performance hit. – AlexCon Mar 19 '14 at 00:51
  • P.S: Have you considered using json rather than xml ? json is native to js so it should perform way better than xml. XML has tags, which makes it bulkier than json, If you can convert your xml to json format and try it, you might be able to see some improvement on the parsing side. For example: http://www.utilities-online.info/xmltojson/#.Uymb5vldWVM – AlexCon Mar 19 '14 at 13:30
1

People have missed one important thing - you are refreshing the code 1500 times...

You are also searching for #list, 1500 times.

function parseit() 
{
   alert("parseit");
   $.ajax(
   {
      type: "GET",
      url: "catalog.xml",
      dataType: "xml",
      success: function(xml) 
      {
          var list = $("#list");
          $(xml).find("Book").each(function()
          {
              var title = $(this).find('Name').text();
              console.log(title);
              listItem = '<li> <a href="#">' +title + '</li>';
              //$("#list").append(listItem).listview('refresh'); - this line we dont want.
          });
         list.listview('refresh');
      }
   });
}

You could even take it a step futher.

function parseit() 
{
   alert("parseit");
   $.ajax(
   {
      type: "GET",
      url: "catalog.xml",
      dataType: "xml",
      success: function(xml) 
      {
          var list = $("#list");
          var listItem = "";

          $(xml).find("Book").each(function()
          {
              var title = $(this).find('Name').text();
              console.log(title);
              listItem += '<li> <a href="#">' +title + '</li>';
              //$("#list").append(listItem).listview('refresh'); - this line we dont want.
          });
         list.append(listItem);
         list.listview('refresh');
      }
   });
}

If you want the listview to responsively add items. You need to make it even slower I'm sorry my friend.

First step.

A. Get the list of books you want to add.

B. Create an asynchronous task using setTimeout

C. Add a few items in that setTimeout, then refresh the list.

D. Make the function call itself again using setTimeout, until all the items from the book list have been removed.

DdD
  • 453
  • 4
  • 19