PageInit binding anamoly in JqueryMobile


The reason:

In JqueryMobile, while traversing in pages within the webapp, JQueryMobile fetches the page and puts it in the current DOM. While this is true for all situations. This might result in a large DOM that eats up lot of memory. JqueryMobile has a way of overcoming this barrier. The JqueryMobile documentation states that

“JQuery Mobile therefore has a simple mechanism to keep the DOM tidy. Whenever it loads a page via Ajax, jQuery Mobile flags the page to be removed from the DOM when you navigate away from it later”.

This can lead to browser specific strange behavior of our web apps. As the amount of cache varies and how the pages are cached also varies. Hence often it leads to multiple ‘pageinit‘.

It’s of common practice to bind the code that needs to be run to the pageinit event. As a result each time pageinit is fired, our function is also called. Now if the function is fired multiple times for the same page, it leads to performance issues. Sometimes due to the nature of code we might not be able to see visualize that the function binded pageinit had been fired twice or thrice. JqueryMobile being a fairly new technology has a dearth of materials across the web. While making the app, we found that the debugger showing multiple service calls instead of just one. While there was absolutely no noticeable changes in the UI, the debugger console showed results as if the page was repeatedly refreshed. While this error has been faced by many developers, there are no articles explaining it.

The Problem:

On careful perusal, I have able to reproduce this problem consistently in Chrome v22.0.

There are 3 html files each having a JqueryMobile “page“.Please refer to the above diagram

Page1 has a link to Page2.Page 1 also has some code that tracks how many time ‘page-init’ event is fired.

Page2 has a link to both Page1 and Page3.

Page3 has a link to page 1.

We start from page 2.

  1. Step 1: We start from page 2.Navigate to Page 1.
    1. Result: page1 fires pageinit event and we get an alert with c=1;
  2. Step 2: We navigate to page2 through the link.
  3. Step 3: We navigate to page3 from page2 through the link.
  4. Step 4: We navigate to page1 again through the link in page3.
    1. Result:pageinit fires twice.c=1,c=2
  5. For each successive iteration through Step 2-step 3-step 4,the number of times page-init fires increases by 1 each time.

This by no way means that pageinit is fired 4-5 times !!. Pageinit is fired only once for each page. This anomaly is because pageinit is binded to the same handler/callback more than once that causes the unpredictable results

The Solution:

To fix the problem we need to call die to unbind the event before binding it to ensure that it will only trigger once. Here is the fix.

Before we attach the function to pageinit event. We write $(“#FirstPage”).die(‘pageinit’);This tells Jquerymobile to unbind all functions from this event. The fix above ensures that only one handler is binded to pageinit event of the page. Hence the problem of repeated binding is gone. While the solution is pretty easy, the problem itself is very subtle but has serious consequences. Pageinit event binding is the best way to initialize the page like loading the data or initializing states. The only problem with pageinit
is that we need manage it in such way that it will not trigger more than once.

Advertisements

One response to “PageInit binding anamoly in JqueryMobile

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s