10 August 2012

Why native development sucks and HTML5 rocks: Porting to Windows 8

Lately, HTML5 mobile app development has received a lot of bashing all over the Internet. Most developers only quickly skim over the benefits and proceed to bash all the downsides. The conclusions they usually arrive at: HTML5 slow, inconsistent, limited and doesn't have a native look and feel. Therefore, native development is superior.

I'm not going to go point by point to defend or debunk these claims today. Instead, I'd like to give an example of the benefits of HTML5.

Here at CreationPal, we make SportyPal - a reasonably popular mobile app that tracks your workouts. Its a native non-trivial app implemented for multiple platforms, so we do have some experience with native technologies.

When we were discussing our new product DoxOut, we concluded that the best way to go is to use HTML5. As a result of this decision, it didn't take much time to port our prototype presentation app to the new Windows 8 UI (formerly codenamed Metro)

The time needed: 1 hour.

How is that possible?

To improve experience, we have a thin native layer for each platform. If a component of the layer is not available, a default HTML5 replacement is provided that works well enough in most browsers. The rest of the code and UI is pure HTML5.

The new Windows 8 UI is all about HTML5, CSS and JavaScript. An application has the same structure as a webpage, with a main html file. What is different is that there are extra "native" libraries available in the global JavaScript namespace which you can use to access native functionality. As a result, it was simply a matter of pointing the app to the relevant HTML, CSS and JavaScript.

Well, not quite.

We quickly got the following error:
JavaScript runtime error: Unable to add dynamic content. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe. For example, using the innerHTML property to add script or malformed HTML will generate this exception. Use the toStaticHTML method to filter dynamic content, or explicitly create elements and attributes with a method such as createElement.  For more information, see http://go.microsoft.com/fwlink/?LinkID=247104.
The new Windows 8 UI has a strict html security model. Directly inserting potentially-unsafe HTML is not allowed, and since we are using a jQuery-based micro-templating library that does exactly that, we quickly ran into the error.

This was the offending line in the jQuery code

// ... snip ...
append: function () {
    return this.domManip(arguments, true, function (elem) {
        if (this.nodeType === 1) {
            this.appendChild(elem);
        }
    });
},
// ... snip ...

We learned quickly that a potential solution is to wrap unsafe execution using MSApp.execUnsafeLocalFunction :

     
append: function () {
    return this.domManip(arguments, true, function (elem) {
        if (this.nodeType === 1) {
            var self = this;
            // In Metro, execUnsafeLocalFunction is needed to
            // append a child which contains arbitrary innerHTML
            if (window["MSApp"]) MSApp.execUnsafeLocalFunction(function () {
                self.appendChild(elem);
            });
            else this.appendChild(elem);
        }
    });
},

As this circumvents protection for all jQuery.fn.html calls,  its not an ideal solution. However the alternative involves giving up features such as data-attributes which was unacceptable.

The only remaining modification was to add the Microsoft-specific CSS properties (such as -ms-linear-gradient) to our LESS mixin classes and $.fn.css calls

Note: jQuery 1.8 makes the last practice obsolete: the newest $.fn.css automatically transforms the property to a browser-specific version, if needed.

After this modification the entire codebase worked flawlessly.


Now imagine the time it would take to port a native app to a new platform.


Despite all the negative reputation, HTML5 remains the fastest way to develop multi-platform apps. The quick porting of our DoxOut Presentation prototype is to Windows 8 confirms that (though not exactly a fair example as Metro is already heavily HTML5-based),  And with efforts such as AppJS, the number of OSes that support mixed HTML5-native development keeps growing.

Switch to HTML5, today!

10 comments:

Unknown said...

I applaud you. I develop native apps only because I desire the raw speed and love the specific UI.

That said, My loyalty belongs to the open web - and it's great to see things like this.

Keep up the good work :)

R said...

from end user perspective.. native apps are desired.

from developer's perspective, you can create the same app in html5 - is prbly faster and easier to create

two sides of a coin

David Stanley said...

Excellent post. I am in the process of getting a web application up and running, and once that is done I hope to use most of my existing html/javascipt/jquery stuff and throw it into the app-world using phonegap.

Unknown said...

@navarr -- sorry, that is like saying, i philander around constantly, but i really do love my wife

Anonymous said...

Well, anything that works for the problem at hand in an efficient manner would rock I guess.

Brad Laney said...

We tried HTML5, but on the slower phones it just cannot perform at all. Even the simplest pages were too sluggish to even consider using. It is just too hard to accept using a technology when someone says "it takes 1-3 seconds to load a static html page".

Brad Laney said...

We tried HTML5, but on the slower phones it just cannot perform at all. Even the simplest pages were too sluggish to even consider using. It is just too hard to accept using a technology when someone says "it takes 1-3 seconds to load a static html page".

spion said...

@Brad Laney:

There are a couple of performance tricks that we've learned in the way, which I might detail in a future posts. One example on android is not using certain CSS properties, such as box-shadow: that alone improves rendering responsiveness several times.

Another important point is page loading: don't do it. Load all code and templates in a single page, then manipulate the page via JavaScript. This way loading time is limited to the first page load (which can be 1-3 seconds), easily solvable with a splash screen.

We've also improved redraw performance while scrolling by sending more touch events to javascript from native code.

In our experience, all phones which are > 1GHz mark perform acceptably smooth. And those that don't have pretty bad native performance too.

Unknown said...

After forced to dump >500,000 lines of our flash codebase to the waste bin, we are only focused in HTML5. With a little effort you can achieve similar look and feel and reasonable performance. There's room to improve, but we see browsers like Chrome, Safari and Firefox behaving beautifully. Our new product funq.tv will be only HTML5, and it will require a minimum set of features to run.

We don't plan to support legacy browsers, or for the matter any other browser with personal interpretations of HTML5. It is a big bet, but as Safari, Chrome & FF provide a superior and smooth experience we don't see the reason to punish our users or to bloat our software.

Long Live HTML5.

Unknown said...
This comment has been removed by a blog administrator.