Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizing code for jQueryMobile: problems with selectively including external JS files only when they are needed

I am using jQueryMobile for a mobile application. Obviously I want the UI to load very quickly, but the application has more than one tool so I want to only load the relevant external JS libraries for the 'pages' when they are navigated to. For the main application (90% of the pages) I just want the jQueryMobile core files (i.e. the latest jquery core from the Google AJAX libraries and the jQueryMobile JS & CSS). However, for the remaining 10% I need Google Maps v3 with geolocation enabled (so the Google Gears external library) and the MarkerClusterer library (I have >400 markers that I want to plot only if I have to).

As I understand how jQueryMobile works (all via internal AJAX requests), you must have all the libraries for the whole application load when the application initializes. This makes my application really heavy when the user first requests the mobile site (all core files, plus all maps/gelocation/marker cluster files). I want to avoid that happening, as it will scare many potential users away (especially when only a subset of my users want the geolocation goodiness).

I have tried loading just the Google Maps components at the end of the relevant page (before the footer div) and also tried putting them into the <head> tag in the relevant page. However both these fail to initialize (checked with console.log() output attached to the functions).

And yes, before you ask, I am using the "pagecreate" live() function and am addressing the correct div (If I put everything related to Google Maps into the root page head tag everything works just fine as it should)

I feel like this must be a pretty common question: selective loading of page components with jQueryMobile. I couldn't find anything online via Google - most jQueryMobile tutorials are the common garden 'Hello World!' variety, so if you have anything to offer I am all ears! Links to selective loading tutorials also welcome!

Thanks in advance!

like image 619
tatlar Avatar asked Oct 11 '22 23:10

tatlar


2 Answers

all those pages initialize all the required libraries on every page.

Yes, that's the default way to do that, so whatever page/subpage is called first by the user - everything works. All the libraries work fine and get loaded only once. But that you probably know.

Assuming you want to load some libraries later, so that they don't slow down the whole app even when the user doesn't need them, you should force them to load with the correct page only.

This can be achieved in some different ways:

  1. The easiest: Put it in the head, asif it was the forst page to be open and put rel="external" in all links to that subpage. It will obviously reload the page and make you loose some advantages of JQM caching pages, but loading libraries in time might be worth it
  2. The advised: JQM should load and run JS when it is put inside the page div. The reason that it failed to work for you is probably that the lib depends on a domready event and you might have to trigger it for the library. But if you just trigger the event, it will make everything (including JQM) handle it. You have to make it trigger only the library. To do that you need to:
    • edit the code and find the event handling function
    • change the code so that the function has a globally accessible name
    • call the function in a pagesomething handler

Also: if you have problems with pages, try binding to a pageshow instead of pagecreate to see if something requires elements to be visible first.

like image 95
naugtur Avatar answered Oct 14 '22 08:10

naugtur


Good question! I haven't seen this in the jQuery Mobile docs. Following naugtur I would say something like this inside your page div

<script>
if(typeof MyFunction == "undefined") {
    $.getScript('myfunction.js', function() {
        // initialize if necessary
    });
}
</script>

If you're loading stuff which Google serves, particularly if there are multiple files, the jsload is a good option.

like image 31
Tim Niblett Avatar answered Oct 14 '22 08:10

Tim Niblett