PDA

View Full Version : Sencha Touch button click slower than list item click?



diwas
12 Aug 2013, 7:08 AM
EDIT: Solution on page 2

I am in the process of profiling Sencha Touch applications and came across the fact that a click of a button triggers action faster as opposed to a click of a list item from Ext.List for the same action. My timeline profiling data indicates that the action is performed on Timer Fired condition for list item. This timer's timeout is 300ms. Now, for buttons there's no timer, so the action is performed as soon as there's touch end (and other Sencha processing common to all clicks).
In my case, the action is a simple transition to another view without any animation.
Following are the screenshot of my timeline data running application on an iPhone 4.
Transition by button click/tap:
45307
Transition by list item click/tap:
45308


I tried to dig into the source code, but could not understand why this is actually happening. My hypothesis is that list waits for that 300ms to see if it was actually a tap action or a scroll action. But is this true? If not, can anyone point me towards the right direction to verify if this hypothesis is true or not?

I also tried with large store, but the behavior is same. List item click takes a consistent amount of time before firing off its callback action (in this case, a transition to different view).


Any help would be highly appreciated!

(I also posted this to StackOverflow (http://stackoverflow.com/questions/18150566/sencha-touch-button-click-slower-than-list-item-click/18154279?noredirect=1))

jerome76
12 Aug 2013, 10:56 AM
I took a look into the Scroller's source code (http://docs.sencha.com/touch/2.2.1/source/Scroller.html#Ext-scroll-Scroller) and noticed there is a config called 'startMomentumResetTime' which defaults to 300 milliseconds. When a List has the scrollable property, it looks like the Scroller is intercepting any actions first before allowing the List to perform its logic.

Have you tried using a List without a Scroller attached to it?

diwas
12 Aug 2013, 11:54 AM
Awesome! The timer was indeed the 'startMomentumResetTime'.

So to use a list without a scroller attached, I'd just do this?
config: { scrollable: false }

EDIT: Just tried this configuration but there's still that 300ms timer which fires off before the logic is run.

jerome76
12 Aug 2013, 12:44 PM
Setting the scrollable to false would prevent scrolling, but I don't think it actually removes the Scroller from the List. It was just a guess :))

I can take a look at the source code more. Lately my Docs have been running like crap so I'll have to revert to the local ones.

diwas
12 Aug 2013, 12:52 PM
Haha, OK. I am looking at the source code too but can't understand it properly. If I do profiling for just single click event, there is a chain of functions and anonymous functions running so didn't really figure out anything from there. Thanks for your help, btw!

jerome76
12 Aug 2013, 12:58 PM
So the List actually creates an inner Container which holds the Scroller.

You can either try unbinding the Scroller's logic or removing that inner Container. I wouldn't advise it, though. You can try it, but I wouldn't :P

In all honesty, I don't mind that extra 300ms so it doesn't try to Scroll instead of Tap - getting rid of that timeout might cause a chance for a little error during execution ;)

diwas
13 Aug 2013, 11:01 AM
Right, my objective was to understand and try to minimize the "action" time as much as possible on list item click. Anyways, I think I'd have to use a different control for my purpose. Thanks for your help!

Also, how did you figure out that the List creates an inner Container which holds the scroller? Can you point me towards the source code or documentation?

jerome76
13 Aug 2013, 12:42 PM
In the beforeInitalize function of the Ext.dataview.List (http://docs.sencha.com/touch/2.2.1/source/List.html#Ext-dataview-List), it pretty much explains it with the comments :P


// Create the inner container that will actually hold all the list items
container = me.container = Ext.factory({
xtype: 'container',
scrollable: {
scroller: {
autoRefresh: !me.getInfinite(),
direction: 'vertical'
}
}
});


// We add the container after creating it manually because when you add the container,
// the items config is initialized. When this happens, any scrollDock items will be added,
// which in turn tries to add these items to the container
me.add(container);


// We make this List's scrollable the inner containers scrollable
scrollable = container.getScrollable();
scrollViewElement = me.scrollViewElement = scrollable.getElement();
me.scrollElement = scrollable.getScroller().getElement();


me.setScrollable(scrollable);
me.scrollableBehavior = container.getScrollableBehavior();

diwas
13 Aug 2013, 1:37 PM
Great, Thanks a lot!

diwas
14 Aug 2013, 7:28 AM
Just tried something different. I created a new Phonegap application with Topcoat (http://topcoat.io/) css library developed by Adobe and there's no significant lag on clicking a list item. Granted that this does not properly check if the action was scroll or tap, but I haven't have any issues trying to tap/scroll. Probably, for the goal of reducing action time on tap, one should use a third party css library like topcoat (If you want to display items like a list). However, this isn't the case for most use cases.

Just leaving it here.

diwas
14 Aug 2013, 12:11 PM
Got it!

This 300ms wasn't because of the scroll event, rather it was to recognize if its a single or a double tap event. If you look at DoubleTap (http://docs.sencha.com/touch/2.2.1/source/DoubleTap.html#Ext-event-recognizer-DoubleTap) recognizer source code, it has a maxDuration of 300 ms in the config object. This is used to set the time out for firing singleclick event.





else {
this.singleTapTimer = setTimeout(function() {
me.fireSingleTap(e, touch);
}, maxDuration);
}


And on every touchStart event, this timeout is cleared.





onTouchStart: function(e) {
if (this.callParent(arguments) === false) {
return false;
}
this.startTime = e.time;
clearTimeout(this.singleTapTimer);
},


To note, this is a private class, so we cannot rely on it. But if anyone wants to decrease the duration between a tap event and firing off its logic, reduce this time. I have noticed that setting it to 150ms will make list item click much much faster, but at the same time, it also opens up the room for ghost click in other screens, since the events are queued up.