Keeping Your App Responsive – Part 1

You are reading part 1 of a three-part series:

Part 1: The Problem

Picture yourself this:

You are busy fooling around with a mobile app. At some point you decide to touch a button. You wait for a full second, but nothing happens. You touch it again, but still no response. Then, right after you touch it for the third time, three windows open in rapid succession. Three identical windows as you notice when you tap the back-button a few times.

Wow, that was bad! This app clearly sucks, right? It’s not responsive! It gave no indication you were supposed to wait. But why should you even have to wait in the first place?! And why does it open the same window three times? It could -and should- have known this behavior was obviously never your intent!

The app sucks. You’ll simply have to download an alternative.

But..

  • This is your app
  • You developed it
  • It’s in every Appstore out there

And you realize every single user of your app will sooner or later stumble upon this same issue and probably come to the same realization.

Ouch…!

So what did you do wrong?

Well, three things to be exact:

  1. You did not show a loading-indicator
  2. You did not prevent the user from opening the same window multiple times
  3. But most importantly: You blocked the UI (User Interface) far too long, causing this issue in the first place

Let’s see what you could do to fix this!

1. Show a loading-indicator

Because you did not show a loading indicator, the user had no idea he apparently was supposed to wait. If you inform your users that their request is being handled they will be more patient.
Even better, by showing actual progress -an interface being constructed, or just a simple loading bar-, their patience will increase. When your users can actually see stuff happening -even if you’re just putting up a show- they will typically more easily accept the delay.

2. Make sure non-repeatable actions are.. non-repeatable

Your app contains a button that when clicked should open a window. Whether this happens immediately or not, clicking it again should not open an additional one. But you did not prevent the button from firing it’s click-event multiple times. Either the button should not have done this, the click-handler should not have executed twice, or the handler should have decided to abort when executed again after the first time. It’s fairly easy to block this behavior, but it is something that is often overlooked.

If you are using Alloy, a simple generic solutions would be to wrap the button in a widget that you will then use throughout your app. Whenever a user taps this widgetized button, save the current time into a property. Before doing this however, first check if this property was already set by an earlier click-action. If it was, compare the property’s value with the current time. If the difference is smaller than 3 seconds (a widget setting), the last click was probably unintended and should be ignored.

Alternatively you could toggle a boolean property and prevent all further interaction until this boolean is reset again by an external process.

Many more variants exist and often it’s not difficult to come up with a good solution. For a very simple solution check out the throttle-function provided by the Underscore library.

3. Don’t block the UI!

Your app contains a button that should open a window… immediately! But clearly this was not the case.

You might think that these stupid delays are due to you using Titanium instead of a native solution, but that is only partially true. You’d be mistaken however if you were under the impression that you simply can’t do anything about it.

Chances are your application was still executing some other code when you tapped this button. Because your application runs in a single thread, that execution was blocking the click-event from being processed.

What this basically boils down to is this: You did not make the best use of your single thread.

To understand how to actually do make the best use of your single thread, you will first need to have a basic understanding of what a thread is and what it means that your application runs single-threaded.

The remainder of this article will explain the basic concept of threads. Part 2 will continue by showing you exactly why your app was unresponsive and part 3 will conclude with demonstrating how to prevent this from ever happening again!

Threads

When a user touches your app’s icon a process -your application- starts (1). It initializes the app, invokes a Controller, opens the first window and then takes a break, waiting for the user to interact with it. When the user then touches a button that should open a different window, the process wakes up again, does some processing and opens the new window (2). Let’s call this process, for the sake of argument, a thread. In fact, let’s call this thread the main-thread.

Now let’s assume the new window that was just opened is to display information obtained from the Cloud. The main-thread opened it and again simply waits for further instructions. Meanwhile, a different process was started that is actively polling the cloud and awaiting it’s reply (3). Let’s call this process a thread as well. When it receives a reply, it processes it after which it will instruct the main-thread to draw some additional Views representing this data (4). Having done this, the cloud-thread closes since it is done while the main-thread pauses again, eagerly awaiting the user to interact.

Let’s additionally assume that when the user does not interact within 5 seconds, the app will do something interesting. So after the main-thread finished showing the cloud data a timeout was set to expire in 5 seconds. When the 5 seconds pass a different process is started that will take care of this interesting event (5). You might have guessed it, we’ll dub this process a thread as well.

Figure 1: Multi-threading
Figure 1: Multi-threading

So, as depicted in figure 1, the main-thread (purple) is the core of the application. It is always there, either active (a box) or pausing (a line). New threads (blue & green) are spawned when needed and when something is to happen that does not rely on the state of the main-thread.

Multi-threading

The scenario described above quite nicely fits the definition of thread by the Free Dictionary. This dictionary defines a thread as:

“A portion of a program that can run independently of and concurrently with other portions of the program”.

So it is a piece of code in your app that can run all on itself and in parallel with other (pieces of code/) threads. In figure 1 (above) each thread is only active when the rest of them are pausing (or nonexistent), but they can actually run simultaneously as well when required. A timeout could be resolved while a cloud-call is being answered and while the user taps a button and opens a new window, all at the same time.

We say a system is multi-threading when:

Threads (can) run in parallel, meaning
 multiple pieces of code can be executing concurrently (at the same time).

Single-threading

All native Android and iOS applications are multi-threaded, which is nice. Why? Because multi-core CPU’s (processors) will actually run threads in parallel when possible. Even single-core CPU’s deploy some nifty mechanisms that allow them to pause a thread half-way and continue with a different one. Making it seem like they are run in parallel.

So it is a good thing then that Titanium applications are also multi-threaded, since they compile to native applications as well. But.. All the Javascript code you wrote to define your app’s logic is executed in a single thread. This means that everything your app is doing happens in a single thread and thus cannot run concurrently (because that would require additional threads).

We say a system is single-threading when:

Code can only run serially, meaning only one piece of code can be executing at any given time.

Figure 2: Single-threading
Figure 2: Single-threading

Figure 1 actually shows how a native app could (potentially) work. Figure 2 however shows how the same scenario works when using Titanium.

Not what you were expecting perhaps? But really, it could not be any other way!

Independent

The definition of thread by the Free Dictionary actually mentions another condition that we did not really emphasize previously. It states that a thread should be able to run independently from others. This means a thread can have absolutely no ties to other threads. It should be able to run on its own, as if it were the main-thread and no other threads would exist to keep it company.

The Android (Java) definition of a Thread gives a more detailed and technical description of ‘independent’:

“A Thread is a concurrent unit of execution. It has its own call stack for methods being invoked, their arguments and local variables.”

So, a real thread has its own call stack and its own local variables. It’s not even that it could exist all by itself, as far as the engine is concerned it actually does.

You might still think your timeout-, and cloud-sync-functions are ideal candidates, but this is seldom the case. Take these pieces of code for example:

var me = this;

setTimeout(100, function() {
    me.doSomething();
});

or

function Class() {
    this.property = '';

    this.init = function() {
        setTimeout(100, function() {
            this.act.apply(this)
        });
    };

    this.act = function() {
        this.doSomething();
    };
}

Both of these delayed functions maintain a reference to ‘this’, which means they have access to the state of a different thread. This clearly violates the independence condition. The same would also hold if these delayed function did not reference ‘this’, but would instead reference a property owned by ‘this’.
In fact, unless your delayed function would conclude with firing an event or showing a pop-up, it almost certainly will communicate with some already existing object to share its result.

Javascript

Chances are almost none of the functions you created could ever run in a separate thread. The reason you never even thought about defining them differently is because you were given no reason. It’s not Titanium’s fault that your application’s logic runs in a single thread. Javascript is by its very nature single-threaded. Originally the language was not created to develop applications, it was simply used by browsers to spice things up when browsing the world wide web.

This actually means that Javascript does not -in any way- support the concept of threads. Your only option is to make the best of it!

What’s Next?

So, now you know what threads are, lets see how Titanium uses them internally. And let’s find out what happens in your application’s single thread that causes it to become unresponsive!

You will learn all of this in part 2!

Ronald Treur is a freelance developer and the co-founder of Snowciety, a multi-platform mobile app created using Titanium & Alloy. He has been developing websites since the age of 11 (starting out on paper due to lack of a real computer) and has been working on mobile apps since Titanium 1.5. For development he has experience with Javascript, PHP and Java and to a lesser extent C and C++. For webdesign he relies on his knowledge of HTML5 and CSS3. Other interests include game-design, movies and talking at meetups (recent addition!).


Comments

  • Nidal

    Very interesting post! I’m waiting with impatience the next step!
    Thanks for the implication!

  • silver jewelry

    A lot of people like how personal and unique photo jewelry can be.
    While buying Gold Jewellery, look for hallmark or trademark apart from the karat marking.

    These tools will facilitate you to accomplish approximately a few basic wire jewelry constructing
    venture.

    Also visit my weblog; silver jewelry

  • Car Town Hack

    I’m impressed, I have to admit. Rarely do I come across
    a blog that’s both educative and entertaining, and let me tell you, you’ve hit the nail on the head.

    The problem is something that not enough people
    are speaking intelligently about. Now i’m very
    happy I stumbled across this in my hunt for something regarding this.

  • Will

    Thank you indeed! For a new developer like myself this is awesome info …

  • Prashant

    Thanks Ronald.
    The whole article was hugely informative & a very rare one.
    I think everyone who is novice in titanium(like me) & doesn’t have much idea about making the app resonsive, must read this great article.
    This article shows the power of Titanium making complex things simple in just little efforts.
    Could anybody here please suggest me any book on Titan which is mainly focus on threading or like making the app responsive..?