YUI App Framework in Cordova

By YUI TeamMay 13th, 2014

Apache Cordova is a framework for developing cross-platform smartphone apps using HTML, CSS, and JavaScript. I recently had the opportunity to create an app for Android and iOS devices, and it was great to be able to do this using familiar web technologies.

One unfamiliar aspect, however, was building a single-page app. It is possible to create multi-page apps with Cordova, but you lose the program state when changing from one page to another, and a lag is introduced as assets for the new page are loaded and parsed. Fortunately using a JavaScript framework makes it relatively easy to build single-page apps, as a long-time YUI user I naturally gravitated towards YUI’s App Framework.

There is good documentation on setting up Cordova, so I won’t go into that. Once set up, here’s all that’s needed to create a new app, using the Android platform as an example:

[~]$ cordova create scotchapp com.example.scotchapp "ScotchApp"
[~]$ cd scotchapp/
[scotchapp]$ cordova platform add android

This creates a www folder for the app’s code:

[scotchapp]$ ls www/
css  img  index.html  js

A Simple App

Let’s make a simple test app, with all code in index.html for simplicity.

First we’ll include Pure (a set of CSS modules that play nice with YUI) and the YUI seed file:

While loading remote assets like this is okay for this sample app, I’d recommend switching to using local copies of the CSS and JavaScript modules once the requirements are settled: we don’t want to rely on devices being connected to the Internet, or make users wait for these resources to download.

Now we can add the code for our app:

And that’s it! We can now run the app on a connected device or an emulator:

[scotchapp]$ cordova run android

This also creates an apk file in platforms/android/ant-build/. If you have an Android device and would like to give it a spin, download the apk for this sample app.

That was pretty easy, but when making a more complicated app there are some device quirks to be wary of: I’ll cover some of those I came across next.

Tap Lag and Ghost Clicks

On iOS and older Android devices, there is about 300ms delay between when a user taps the screen and the click event is fired. This is because the device is waiting to check for a double-tap. You can get rid of this delay by adding YUI’s event-tap module and listening for tap events rather than click events:

YUI().use('app', 'event-tap', function (Y) {
  // ...
  events : {
    'button' : {
      tap : function (e) {
  // ...

There is, however, a catch: ghost clicks. A tap event will fire instantly, but the click event will still fire after 300ms, and can even trigger an action on a new view the app has just rendered. I ended up using a transparent <div> with a high z-index to capture ghost clicks when transitioning between views, removing it after 400ms, but I can’t claim that’s a very elegant solution.

Other Quirks

Cordova and YUI both support Android devices back to version 2.3, but there are some quirks. Cordova’s device detection can be used to trigger different code paths depending on what OS the device is running.

Android devices use an overlay with a list of options when a user taps a <select>, but Android 2.3 can fail to detect <select> tags when they’re added dynamically, for example when rendered in a Y.View. I ended up using <radio> tags on Android 2.3 devices as a replacement.

Once a Y.View has rendered, adding additional dynamic content with setHTML() to one of its nodes can cause all content to disappear in Android 2.3. For example, if data for a table in a view needs to be loaded from a remote source, it might be nice to:

  • make an AJAX request for the data,
  • render the view,
  • update the view’s table once the AJAX request has completed.

But on Android 2.3 I found I had to fetch the table data then render the view, otherwise I ended up with a blank screen when trying to update the view.

On a couple devices (HTC One X on 4.2.2 and Samsung Galaxy Note II on 4.1.1), I found that after the app had rendered its initial view, navigating to a new view didn’t work with transitions enabled. Try setting transitions: false when initializing Y.App if you think you’re hitting the same issue:

var app = new Y.App({
  transitions : false,
  // ...

Closing Thoughts

Overall, YUI’s App Framework and Apache Cordova make a great combination, I’d certainly use it again. If you have a team with experience building websites and want to start also making mobile apps, this might also be the right choice for you.

Full Code Listing

Jackson PaulsAbout the author: Jackson Pauls is a Holistic software engineer based in Edinburgh, Scotland.

5 Comments

  1. It’s nice to see some attention devoted to YUI 3 on mobile. However, I think that the blog post would be more interesting if the application went a beyond the hello world stage.

  2. […] Pauls wrote an article on our own blog this week about using the YUI App Framework to create cross-platform apps using Apache […]

  3. […] Pauls wrote an article on our own blog this week about using the YUI App Framework to create cross-platform apps using Apache […]

  4. How is the mobile performance using app framework and Cordova? Does it feel like a native app, or does it have the web app trying to be native jerkiness? I tried your APK and it seems ok, but not enough going on to be able to tell how it would perform overall.
    Any thought to using Steroids.js from Appgyver? It supposedly lends better performance over Cordova alone.
    Also, FT’s Fastclick.js solves the 300ms type issues well. May be something to consider.
    Thanks in advance,
    -Chad

  5. Jackson Pauls said:
    June 2, 2014 at 4:49 am

    Chad, thanks for your thoughts. I haven’t hit any inherent performance issues in an app with more content and user interaction, starting the app is quick and interactions are smooth. Steroids.js looks interesting if you really want to optimize performance, but I haven’t tried it. One consideration is that it doesn’t look like it supports as many platforms as plain Cordova.
    I tried Fastclick.js, but it didn’t work out of the box for me on iOS. I’m not discounting it (I didn’t dig too deeply to find the problem), and would try it again if needed.

Leave a Comment