The first secret of a good jQuery Mobile architecture is knowledge. If you don’t understand this, you are doomed to fail.
 
jQuery Mobile is notoriously difficult to implement correctly. Before you start coding make sure you have everything specified down. At least have wireframes of your project because page structure is most important architecture point.
 
There are two possible ways how a jQuery Mobile page skeleton can be created. As usual the truth lies somewhere in the middle. Both templates have good and bad sides, and we can play with them, especially if we know their bad sides and how they affect overall application functionality.
 
 

Note: If this tutorial was helpful, need further clarification, something is not working or do you have a request for another Ionic post? Furthermore, if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here, again leave me a comment below. I'm here to help you, I expect the same from you. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com, or follow and mention me on twitter (@gajotres). Thanks and have a nice day!


 

Multipage template

 
First and classic one is a multi-page template where one HTML holds all available pages. This is also a first template shown to new jQuery Mobile developers. It is also the easiest template to implement, of two available:
 
<!DOCTYPE html> 
<html> 
    <head> 
        <title>Page Title</title> 
        <meta name="viewport" content="width=device-width, initial-scale=1"/>  
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
    </head> 
    <body> 
        <div data-role="page" id="page1"> 
            <div data-role="header">
                <h1>Page Title</h1>
            </div><!-- /header -->
            
            <div data-role="content">	
                <p>Page content goes here.</p>		
            </div><!-- /content -->
            
            <div data-role="footer">
                <h4>Page Footer</h4>
            </div><!-- /footer -->
        </div><!-- /page -->
        <div data-role="page" id="page2"> 
            <div data-role="header">
                <h1>Page Title</h1>
            </div><!-- /header -->
            
            <div data-role="content">	
                <p>Page content goes here.</p>		
            </div><!-- /content -->
            
            <div data-role="footer">
                <h4>Page Footer</h4>
            </div><!-- /footer -->
        </div><!-- /page -->
    </body>
</html>
 
As you can see, one HTML holds all available pages. While this may sound silly to a normal web developer, it is quite an excellent solution. This kind of template solution don’t suffer from page transition problems like template solution using several HTML pages (we will discuss it soon). Because jQuery Mobile uses Ajax for page loading delays should be expected, same delays that could cause problems with page transitions. As everything is already loaded into the DOM multipage template will no suffer this kind of problems.
 
On the other hand, this solution also holds one severe problem. Mobile web application can take a sizable part of the DOM and while this is not an issue for desktop browsers it can cause problems for mobile devices and its accompanying browsers. Also don’t forget that we are talking about the framework made for a mobile web applications.
 
Several pages may not feel that much but think what would happen if a web application has complex page structures (and I have seen jQuery Mobile pages holding several hundred form elements). What you see as a page HTML is not final HTML. As jQuery Mobile loads pages, it enhances them with its own CSS.
 
The final HTML structure can be 2-8 times larger than initial HTML, and everything is done dynamically. This leads us to this templates second problem. More content means more processing power is used/need to enhance page content, and jQuery Mobile is one large hungry beast.
 

Multi HTML template

 
A second template solution is also called multi-HTML template. Unlike multipage template, this one uses several HTML pages for application skeleton. This solution should feel much closer to experienced web developers, and it can be easily used with server-side page generation.
 
This solution has a significant advantage over a multipage template. Only initial HTML is loaded into the DOM, which makes it a memory-friendly approach. Pages are loaded into the DOM only when directly accessed (or loaded through a caching system) and unloaded as soon as a page is not active anymore. From the practical side this is excellent, pages are readily available, not to mention shorter.
 
This may look like the best solution for a mobile web application, but there’s one big problem. Page transitions can become problematic because every HTML file needs to be loaded first before a transition can occur. This is more prominent when working with mobile devices, especially when using Android 2.X platform. A second problem comes from page unloading. Because pages are loaded/unloaded each time they are used pageinit event will trigger every single time page is active.
 

Best application creation approach

 
This part will talk only about pure vanilla jQuery Mobile approach.
 
Before creating an app think about it, what do you expect it to work and what would be the page flow. To create best-behaving application we need to combine both templates.
 
  • Frequently used pages MUST be part of a first HTML file, this will prevent most transition problems
  • Everything else should be moved to other HTML pages
  • Subsequent HTML pages (every page that is not initialized first) can have ONLY 1 page, everything else is going to be discarded
  • Secondary HTML pages javascript and CSS must be initialized inside a same page BODY or inside a first HTML, explanation can be found HERE
  • Frequently used pages, for example, pages used to show various content (like news articles) can also be created dynamically.
  • Pages should not be complex. If possible split your content to several pages. If this is not possible don’t overuse jQuery Mobile widgets, they are the main reason for a slow application performance.
  • Never use more than 20-30 listview elements per page. If this not possible then use some kind of pagination system and always remove previous elements.
  • Dont use page transitions if you don’t need them
  • Use delegated event binding and always prevent multiple event binding. Solution can be found HERE.
  • Dont use CSS3 features for older Android and iOS platforms. CSS3 text shadow is a performance killer on Android 2.X platform, not to mention transition effects.
 
 

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.

Blogs worth reading

If you're here looking for information related to the Ionic Framework, you will also like these blogs:






  • Pat Breslin

    This is a very helpful article. If I have a web-based manual with about 50 pages, including graphics, would it be better to use the multi-page or multi-html approach? If I use the multi-page approach, is there an approximate file size where performance will be seriously impacted? (Sorry for the questions, I’m a newbie).

    • http://www.dragan-gaic.info Gajotres

      You should use multi-HTML approach, your first page should contain only highly used pages. Everything else should be used only when needed and removed when not active.

  • http://www.philecomsolutions.com David Addoteye

    Your article is surely a solution to a fundamental problem in Jquery and Jquery-Mobile site and apps. I will like to thank you for taking your time to write and share your knowledge and experience.
    I have three major question i will like to ask,
    I am creating a phonegap app with Jqeury-Mobile, my questions are;
    1) Should I repeat jquery.js, codorva.js, jquerymobile.min.js and their associate .css on every html page.
    2) woudnt there be a conflict since the same (.js)files are being loaded into the DOM without page refresh.
    3) What is your advice on uses of “prefetch” to pre load html pages.
    Thank you

    • http://www.dragan-gaic.info Gajotres

      First thank you on your comment, now let me answer your questions:

      1) You should repeat it and let me explain why. First when jQuery Mobile loads additional HTML files it will strip HEAD content. So why should you them include them? Sometimes error can occur thus removing app content from the DOM. In this case app will refresh it self and page will fully load into the DOM.
      2) I have described it in answer no. 1. If page HEAD already exist in the DOM jQuery Mobile will never load another HTML files HEAD unless previous page content is fully removed from the DOM. I can’t think of the case where one HEAD is going to be loaded while other one is still there.
      3) Prefetch can help you keep you app small. Use it only to load pages you know will be used next or soon. This will prevent large DOM size and at the same time page transition sill look nice because page is prefetched when needed. Don’t forget to remove those pages afterwards.

  • http://realmdigitalmedia.com Rajul

    hi

    I have Working on a JQM project where i am using first screen that has dropdown and few list item. Clicking on the list i am opening a dialogue. Clicking a buttton in dialogue i am loading another html page. But on this screen i am seeing previous page element that is Dropdown. It feels like this element has top most z index such it obviously noticable.

    Do i have to expclitly remove this contorl button from DOM ? Does not JQM natively take care of previous screeen elements? Please help.

    • http://www.gajotres.net Dragan Gaić

      You don’t need to more anything, jQuery Mobile handles it on it own. If possible recreate your case inside a jsFiddle example and I will fix it for you.

  • Mukesh

    HI i am using requirejs to load related jquerymobile files even framework files also…. something like tha.

    requirejs.config({
    baseUrl: ‘scripts/’,
    paths: {
    ‘jq’: [‘//code.jquery.com/jquery-1.9.1.min’, ‘lib/jquery-1.9.1.min’],
    ‘jqm’: [‘//code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min’, ‘lib/jquery.mobile-1.3.2.min’]
    },
    shim: {
    ‘jqm’: {
    deps: [‘jq’],
    exports: ‘jQuery.mobile’
    }
    }
    });

    require([‘jq’, ‘jqm’], function(){
    /*
    once JS loaded
    ‘.no-js’ class will be removed from HTML tag
    */
    $(‘html’).removeClass(‘no-js’);

    });

    .no-js css class used to hidden the page till JS not loaded fully. is there any better solution.

    Regards,
    Mukesh

    • http://www.gajotres.net Dragan Gaić

      So sorry I can’t help you here, I was using require.js with backbone and jQuery Mobile and only thing I can tell you is to run from this combination.

  • http://montage.viavistas.co.in/jm/ajd.html Ashish Pawaskar

    Hi,

    Thank you for this article I was looking for a sane explanation of multiple pages using ajax.

    I have created two pages at: http://montage.viavistas.co.in/jm/ajd.html

    This works perfectly on the browser, but If I open the file locally in chrome, the first page (ajd.html) opens, but clicking on the link (thisme) fails with the console showing the error:

    OPTIONS file:///C:/Users/Ashish/Desktop/thisme.html No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘null’ is therefore not allowed access.

    Can you please advise what am I missing? :(

    • http://www.gajotres.net Dragan Gaić

      Chrome is problem here.

      Solutions:

      1. Open it in Firefox
      2. Or if you still want to use only Chrome, then install XAAMP or WAMP (or any Linux/Mac version if you use that OS) and run test those files from XAAMP/WAMP htdocs/www directory.

      OR just google this error, it is a common problem when working with Chrome.

  • Fai Wong

    Hi Dragan, if there is a page which loads data (dynamically from JSON retrieved from remote server) to form the items of a ListView, how can it be prefetched? Also if a user were to click on one of these list items, should the target pages (which loads more details about the list item) be prefetched too?

    • http://www.gajotres.net Dragan Gaić

      You can prefetch it any time you want but you should be careful not to do it while jQuery Mobile is rendering page content. Usually it is best to load it after page has been shown, just initiate ajax call + display ajax loader so user can now something is going on.

      Second question depends on you dynamic data size and page complexity. If page is not complex just load it with an initial HTML file. Or usually best solution would be to create it on the fly, best time would be during ajax call. You only need to create it and insert it into the DOM, jQuery Mobile will handle the rest.

  • tony

    this is good and the multi html system is the best. BUT as you say each page should repeat the full html (doctype,js,css, body…) and not just the content for the main page i.e. the data-role=page div.

    this is annoying as you duplicate all the html and have to edit every page for an edit. with server PHP you would put all the code in head.php/foot.php. with html you would use maybe SSI server side includes.

    nobody seems to have a solution to this and its bloody annoying like having to go back to the bad old days of dreamweaver templates or find/replace.

    there must be a way to avoid repeating the following in every page?:

    Single page template

    • http://www.gajotres.net Dragan Gaić

      Why don’t you use some kind of template engine? It’s something I would advise you to use. I’m not using it in my examples because I’m trying to make them as simple as I can.

  • Aravinth A

    I have multi page(single HTML file divided into pages) app using JQM. i need to pass param from first page to second page vai url (got success) after that i need to pass new param from second page to third page when view the url in third page still it shows the first page param. And one more problem is want to refresh the current page(like third page) so use reload : true but it goes whole page (all three pages reload ).

  • Scorpio

    Good explanation about jquery mobile page architecture. Please wrote a blog about mustache.js + jquery mobile + jquery. The templates are loaded from .html pages at the run time(there are several html page like 1.html,2.html… these are loaded in runtime and our index page contains only scripts) . I search this type of example but not find it anywhere.

    Thank You.

  • Gonzalo

    Hello Dragan.

    Thank for your posts!

    As I understand here, you are talking about having a main page with the frequently used, and then adding or removing to this one other pages, I will explain what I understand with an example:

    File index.html:
    data-role=”page” id=”main”

    Then loading another page to this file, will lead me to:

    File index.html:
    data-role=”page” id=”main”
    data-role=”page” id=”otherPage”

    Is that right, or loading another page (in another file) will erase the previous loaded pages.
    Can you give me, make, and example of how to handle this?, i mean, loading and erasing pages. =)

    Thank you!

    • http://www.gajotres.net Dragan Gaić

      If AJAX is used for page handling (default state):

      1. Every page found in index.html will always stay inside the DOM (unless you remove it manually)
      2. Pages found in other .html files will load only if you transition to them. They will be removed after you transition from them to some other page (unless page caching is turned on)
      3. Other .html files can have only one data-role=”page” (you can have more than one but jQuery Mobile will always load only first one)
      4. index.html can have as many data-role=”page” as you need

      • Gonzalo

        Hello Dragan, very clarifying!

        So for the hybrid AJAX is needed. So one data-role per html (other than index). As I am concerned, if you want to load more than one data-role=”page”, ajax need to be disabled.

        Last one: Suppose this:
        File index.html File other.html
        data-role=”main” data-role=”other”

        So if I am in “main” and transition to “other”, it will be inserted in DOM. And then transition back to main, other will be automatically removed, is that correct?

        What about maintaining state, for example back button? If transition to another page, remove “other” from the DOM, implies I can’t go back there?

        Thanks a lot!

        • http://www.gajotres.net Dragan Gaić

          You are correct, “other” will be removed.

          jQuery Mobile will maintain the state and you have two options:

          1. You can tell jQuery Mobile to cache the page if you want to remember data shown on that page
          2. Or you can create a logic that will repopulate that page when you finally transition to it

          Both options are viable, but you need to decide which one is better on a short/long term and which one is faster. I would cache most frequently visited pages and rebuild less visited ones. Just be careful not to cache extremely large pages. For example, let’s say you have a large listview, there’s no need for 100+ elements, add/remove them on the fly, just make it user/performance friendly.