Monday, January 31, 2011

Why real time feed does not make sense for a news service

I am a news savy or I try to be one. I would like to know about the topic as soon as possible. Recently, people started talking about real time feed. And when they say that, they essentially means Twitter feed. They are real time feed because people are tweeting about it somewhere out in real world. In contrast, a search result on web is not considered real time as those are indexed by a web spider at some point of time. That means, ideally real time feed is the best place for me to check about the latest topic. Ok, that make sense. I go to twitter and look at the trending topics. But that just tells me about the topic but not what about it. Sure, I can then look through what people are talking about it. But most of the time, a tweet in itself does not make sense. Sometime people emote about the item. Sometime people talk in twitter code language that I can't understand. After spending some more time, I might be able to understand what the heck is going on. That's OK way to know about something. Let's see the alternative. I take a trending topic and I do a Google/Bing news search. I tried this for some of the trending topic. For most part, I got some very recently published article about it. In this manner, I get all the information at one place and I do not need to compose a story from multiple tweets.

This brings me back to where I started this article. Where should I go to get the recent news? Why would I ever want to start with real feeds at first place ? A news aggregator/indexer service such as google/bing anyways surface those articles quickly. So why would I ever bother about real time feed ?

Saturday, January 29, 2011

Cross domain requests - how it is not scalable for Mobile Web

Many times, you might want to download data from a service hosted on a different or a sub domain. The usual approach is you add a script tag in your DOM with src tag set to the request url. The request url in turn returns javascript that calls a javascript function on your client passing the data as an argument to that function.

However, this technique is not scalable for all mobile web browsers. I know for sure that this technique fails on HTC Incredible. I will tell you why in a moment. But to verify my claim, I went ahead and looked at Google mobile site. Google Mobile usually hosts its autosuggest service on a different domain (for many reasons - less load on their main production server, increasing maximum number of parallel connections etc.). Look at the server to which the browser makes request for an iPhone and HTC Incredible UA:





As you can see, Google clearly differentiates between these two phones in the way it make request for autosuggest, for iphone case - it uses cross domain request and for HTC incredible, it uses ajax to download the suggestions. What essentially happens in case of HTC incredible is browser gets in old state. If you keep making requests using the same script tag or creating new script tags or each request, the browser does not evaluate the script response from the server immediately. But if you give some sort of poke to browser (by either touching the screen or by invoking alert etc), it will invoke all the pending functions call immediately.

I wonder on how many other phones this behavior happens. I hope not a lot.

If you wonder how I produced these waterfall chats, by ofcourse faking the UA from my firefox browser. But may be in future, I can use steve souders bookmarklet to produce waterfall directly on mobile devices.

Tuesday, January 18, 2011

Mobile browser market share in US

This graph indicates mobile browser share of total mobile internet traffic in US market in past 12 months. Datasource: StatCounter



Trend is clear. More and more mobile traffic is coming from non-iOS devices. On an average over the year, this is how the share looks like

Blackberry: 29.57%
iPhone: 26.83%
Android: 18.02%
iPod: 13.88%

Note that the above will not total to 100% as I omitted share for other browsers such as Opera etc as these 4 constituted the top 90% traffic source. Note that all the 4 devices have a webkit browser with HTML 5 capabilities (Blackberry announced it last year). This is good news as HTML 5 features would help to a create a user experience which would feel like native app.

Write once and run everywhere ;)

EDIT: I just found out that Google recently released the relative number of active devices running a given version of the Android platform.

Friday, January 14, 2011

Mobilism - 12th & 13th of May, 2011: Amsterdam

I recently came to know about Mobilism, the first conference that exclusively focus on web design and development on mobile devices. I am happy to see that mobile web development is getting more and more traction. Few days back, Steve souders, the famous author of High Performance Website and Even faster web sites, also announced that his research wings will now focus on finding bottlenecks and building tools for mobile websites.

With so many different mobile platforms becoming popular,I believe that the only way to deliver a kick ass experience without creating a big engineering effort is build the experience in html(5) and deliver it through web.

Go Mobile !

Sunday, January 09, 2011

Enter keyboard event with animation on Samsung sch-i400

In this post, I am going to talk about a very surprising animation bug on Samsung SCH-i400 running on Android 2.1 OS and what I had to do to overcome the problem.

The other day, I was trying to perform some animation when the input field gets focus . Let me be specific. I have a text input field and when it gets focus, I want to move the input field towards the left as shown in figure. After the animation is complete, I want to run some validation logic once the user submits the form.


<style>
.normal{margin-left: 50px;}
.animate{margin-left: 0px;-webkit-transition: all 0.3s ease-out; }
</style>

<div id="sb" class="normal">
<form>
<input id="q" name="q" type="text" value="flowers" onfocus="OnFocusEventHandler(event);"/>
</form>
</div>

function OnFocusEventHandler(e)
{
var ele = $("sb");
ele.className = "animate";
}


OnFocusEventHandler changed the css class of the input field container which essentially performed the animation. This worked so far. As I mentioned in one of my previous blog post, I hooked up the validation logic to keydown event of the input field. But to my surprise, when the user tapped on "return" key on the keyboard, the keydown event handler never got fired ! Browser also didn't fire submit event on the form.

To debug the problem, I tried animating the input field by clicking on a button, putting focus on input field manually by tapping on it and then submitting the form by hitting the "return" key. This time everything worked fine - keydown event handler got called and the validation logic ran just fine. I also tried attaching the animation logic to mousedown / touchend events of the field but met with no success. With some more experimentation, I found that if I move the input element as soon as it gets focus (and at the same time browser brings up the virtual keyboard), the keyboard events are not properly attached to the input field.

Then I tried the obvious thing - I waited for sometime after onfocus event to begin the animation by using Window.setTimeout. And that did the trick. I set the delay of 500 ms (100, 200 ms etc didn't solve the problem) before I started the animation. Essentially I had to wait for the keyboard to become visible completely before I can start the animation.

function OnFocusEventHandler(e)
{
window.setTimeout(function()
{
var ele = $("sb");
ele.className = "animate";
}, 500);
}


I was hoping that a very simple thing like this would just work out of the box. But it didn't. Sad Web Developer :(.

Backspace event on input fields

As a part of my job, I had to write code which would do something when the user hits the backspace on an input field (type=text). At first glance, this looked like a piece of cake. I listened to keydown event of input field and invoked the logic when the event keycode is 8 (browser sets the keycode of the event to 8 on backspace).

function OnKeyDownEventHandler(e)
{
if(e===null) e=window.event;
if(e!= null && typeof e != 'undefined')
{
if(e.keyCode===8)
{
// That means user tapped on backspace
// Run your logic here
}
}
}

This logic ran smoothly on all the different versions of iOS (iPhone and iPod). But this logic would fail on iphone 3 and lower devices when the value of the input field is empty. In that case, for some reason, browser would fire event with keycode as 127 and that too multiple times ! So, I had to make sure that I would listen for event with keycode of 127 and also had to make sure that I invoke my logic only once by maintaining a boolean flag. Also note that some android devices, for example, Samsung Focus (Android 2.1 and I think on 2.2 also) would not fire any event when the value of the input field is empty and user hits backspace. There were some other android devices which had the similar.

In short, you would expect simple things like this would work on atleast webkit browsers on mobile devices but sadly it does not. Make sure you know which devices you are going to support for your application and test your logic on those devices ( running on different versions of OS too, my experience tells me that Android 2.2 is well behaved than Android 2.1) and test your application with extensive test cases.

Saturday, January 08, 2011

Html form validation on a webkit mobile browser

In this post, I am going to talk about how can we run validation logic on form fields on mobile webkit browser and stop it from being submitted if the validation fails and submit it if the validation passes. It is well known that if the browser/ or your javascript code has invoked the submit event on the form, it is too late to run the validation logic i.e. you can never stop the browser to submit the form if the validation logic fails. Even if you try to set the return value of the event to false or if you try to stop default action from submit event handler. I always use the following method to kill an event

 // e: Event
function stopEvent(e)
{
if(e===null) e = window.event;
if(e!=null && typeof e != 'undefined')
{
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropagation) {e.stopPropagation();};
if (e.preventDefault) {e.preventDefault();};
}
}

On mobile devices, user would submit a form by hitting "Go" or "Search" button on iPhone or "return" button on Android unless you have your own submit button on the page. When the user hits the button, browser would fire the submit event on the form and if you call stopEvent method from your form submit event handler, the browser would still submit the form. So in order to solve the problem, we need to get hold of an event that browser fires before it fires submit event on the form. If we can find such an event, then we can run the validation logic in that event handler and stop bubbling of the event if the validation logic fails. In that case, submit event would never be triggered on the form and we will achieve our goal.

In my case, I have an input field (type=text) and for discussion purpose, I just want to make sure that the value in input field is not empty. The way I solved this problem is by running the validation logic in keydown event handler of the field. When the user taps on "Go" or "return" button on the phone, browser sets the event keycode to 13. So assuming OnKeyDownEventHandler is your event handler for keydown event, you can do the following:

function OnKeyDownEventHandler(e)
{
if(e===null)e=window.event;
if(e!=null && typeof e != 'undefined')
{
var keycode = e.keyCode;
if(keycode===13)
{
// IsValid runs the validation logic
if(!IsValid())
stopEvent(e);
}
}
}

Note that on iPhone 3 (not sure below iphone 3), browser sets the keycode to 10 instead of 13. So you to make this logic work on iphone 3 and above, you need to run the logic when the keycode is also 10.

function OnKeyDownEventHandler(e)
{
if(e===null)e=window.event;
if(e!=null && typeof e != 'undefined')
{
var keycode = e.keyCode;
if(keycode===13 || keycode===10)
{
// IsValid runs the validation logic
if(!IsValid())
stopEvent(e);
}
}
}

Some might argue that other browsers might fire keycode 10 for a different key and this would break the logic. True. But practically I have never came across such a situation. If you want, you can do device sniffing by getting the UA and running the logic for keycode = 10 only if the device is iphone with version 3.