back to blog

HTML5 Enterprise Application Architecture

March 10th, 2013, Updated September 2018, by jeremy

Now that we have a good understanding of HTML5 for applications, we can jump right into the HTML5 application architecture. The most important aspect of a good architecture is the independence and integration of all the parts of the system (i.e., integration should not be a factor of dependence). In other words, we strongly recommend lightweight, modular frameworks or libraries that do one or two thing well over the do-it-all mega-frameworks (e.g., Sencha) that try to do too many things, often in their own way (and not the HTML/CSS/JS way).

From bottom to top:

1 HTML5

The base of all HTML5 applications is obviously the browser runtime with HTML, CSS, and JavaScript runtime. As mentioned before, it is important to realize that HTML5 is HTML, and it is relatively easy with some good best practices to build an HTML5-optimized application while maintaining compatibility with older browsers such as IE7 and IE8. In a well-architected application, adding IE7 and IE8 support adds about 15% on top of the HTML5 version, which is not free but definitely lower than any other alternative.

2 DOM Access API

jQuery provides a very clean, powerful, and flexible API to access the DOM and does a great job of normalizing DOM access across browsers. jQuery has also some very good utility APIs, such as Deferred, that are critical for enterprise application development (more on that later).

jQuery library has become a de facto standard for good reason: because it does what it does better than any other libraries (by a long shot). Developers should not hesitate to use it in their mobile, tablet, and PC applications; it will normalize their DOM access as well as minimize a lot of boilerplate code to manipulate the DOM.

Kudos to John Resig for his novel approach to DOM access and manipulation. jQuery makes building DOM access concise, efficient, and even fun!

Note While jQueryMobile and jQueryUI sort of resulted from jQuery, their respective designs are far from exhibiting the quality level of the jQuery API (in our opinion). In fact, we think that jQueryUI and jQueryMobile, while they do have some nice UI styles, have a fundamentally flawed design for large- or even medium-scale applications (without mentioning that it does not make sense for any framework to be mobile- or PC-only). Thus, in short, developers should not think twice before using jQuery but should really be extremely careful about using jQueryMobile or jQueryUI. (Sorry for the bluntness of this note. It is nothing personal against the jQueryMobile or jQueryUI developers, but this site is about sharing our experience in building high-quality HTML5 applications, and for this, we decided to share our points of views in an unfiltered manner.)

Thus, our strong recommendation is to use jQuery for your mobile, tablet, and PC applications without a second thought.

3 UI Elements

Understanding the taxonomy of HTML UI elements in your application is probably the most important understanding for your architecture. This understanding can drive you the right way or the wrong way.

In short, there are two different approaches.

The first approach, which we do not share at all, is represented by frameworks such a Sencha, SproutCore, and, to a lesser extent, jQueryMobile/UI, and the premise is that HTML/CSS is not really optimum to do application elements and layouts and that, consequently, an application framework must provide a meta-layout language, a large set of UI widgets, and a "desktop-like-object-oriented-way" to code and extend those widgets. With these approaches, developers do not code much in HTML/CSS but, rather, in a "framework meta-language" to do the UI Layout, even on that is object-oriented (in Sencha). The framework has a set of proprietary frameworks or meta-tags on HTML and requires some relatively heavy pre- or post-processing of the DOM in JavaScript (which will prove to be a big constraint down the road). The big problem is that developers learn the "framework way" to do HTML5 layout/UI, which they will realize is inflexible and overly complex, and most of them will find that it distracts them from learning the technology that really matters, HTML and CSS.

The second approach, which we are undeniably in favor of, is extremely well-represented by Twitter/Boostrap, assumes that HTML/CSS is actually a great way to do content and an application layout, and provides a first set of reusable and clean HTML/CSS UI elements, as well as showing, by example, some of the best practices to build well-structured HTML/CSS UI components. The key part of these UI components (here called "UI elements") is that they do not require JavaScript for display (while you can obviously add JavaScript for behaviors in a later stage). This display v. behavior decoupling the secret to build very advanced application with minimal complexity (contrary to what the first approach’s developers/evangelists think). When building advanced applications the DOM is your friend, not your enemy, and Twitter/Boostrap makes a great introduction to this new friend.

Therefore, our recommendation is to do the base UI element the HTML/CSS way (no JS required for display), and once you get those right, you will see that your applications will be much simpler and scale much better. Twitter/Bootstrap is a great starting point that will give you a first set of robust HTML/CSS UI elements as well as showing you how to build clean and flexible HTML/CSS application UI elements.

2018 Updated: We now do not use Twitter Boostrap anymore, as CSSGrid is offering a transformative way to do layout natively to the browser, and Google Material is a modern and holistic design specification.

Note Obviously, many UI elements needs to have behavior as well, and for this, JavaScript is required, but the point here is to decouple the rendering from the behavior, which will give you much more flexibility as to when to add the behavior, which will, in turn, give great flexibility as well as performance benefits (e.g., using delegates for some components).

4 Templating

One of the critical components of any modern HTML5 application is templating. In the Web 1.0 days, browsers could not (or at not least easily) asynchronously fetch data from the server, so the practice was to have templating done on the server and send the HTML with the merge data to the client. In the Ajax/HTML5 days, this changed completely, and now any modern application does some or all HTML rendering on the client side. Building HTML in JavaScript code itself is very cumbersome, not readable, and error-prone. Thus, it is strongly recommended to use a template engine that merges HTML content (usually content with a script tag of type="text/html" or something like that) with a model (usually a JavaScript object or array) and to create the HTML that can be added to the DOM.

There are quite a bit of JS Templating, such as Mustache, Handlebars, and the newest addition coming soon out of alpha, JSRender.

There are quite a number of JS templating engines, such as Mustache, Handlebars, and the newest addition coming soon out of alpha, JSRender.

We like to use Handlebars.js, because it is mature, extensible, not as constrained as Mustache but still promote good coding practice, and has a way to precompile the templates that can be very useful for performance or Chrome App support (which does not support eval or new function).

5 Data

On the data side, JSON is the data format to follow, as it is natively supported by the client and widely adopted in the various server environments. Beyond the data format, a well-architected HTML5 application needs a simple but robust data access layer that allows the decoupling of the views from the data, and this is exactly what an MVC, such as brite.js, should provide.

There are two important capabilities that any data access layer should provide:

Asynchronous data access: This is a must for any real application. The application (views and logics) cannot assume that the data will be accessible in a synchronous manner. Many MVC frameworks make this mistake, and the application code needs to work around this oversight. A robust data access layer exposes all the CRUD API in an asynchronous manner. The brite DAO follows this pattern and uses the jQuery.Deferred model. Data eventing model: The next important point of any data access layer is its eventing model. This is usually well-understood by the framework maker. For example, brite has a simple but powerful event system with a jQuery type of selector (e.g., brite.dao.onDataChange).

2018 Update: In 2018, we now use mvdom Pub/Sub for data event notification (Daos belong to the app, not the framework).

6 LightWeight MVC

There are two ways to implement MVC in an HTML environment, the widget/desktop way, which consists bringing all the desktop MVC patterns to HTML – Sencha is a good example of this – or the "DOM Centric" way, which consists of using the DOM model as much as possible and just adding the missing MVC pieces.

At BriteSnow, we take the second approach, as we think it yields better and simpler application code, and greater performance, and optimized applications. We actually built over a year a lightweight, robust, and powerful DOM-centric MVC on top of a jQuery core, brite.js.

brite.js brings the following two missing pieces to the DOM/jQuery programming style:

A view model that provides us with a well-structured and scalable view model for advanced applications. A DAO model access layer that provides a pluggable and asynchronous data access layer with a jQuery-like eventing model.

2018 Update: In 2018, we now use mvdom, a DOM Centric MVC famework, which could be described as brite.js next gen (very similar API), which ZERO dependency, provides full async view lifecycle, simple and powerful pub/sub api, delegate even binding, as well as some, and best of all, MVCOM is the smallest DOM MVC framework (15kb minimized, 7kb gzip). Smaller is smarter in the world of JS Framework.

7 Application

On the application side, the code needs to be well-structured and componentized, and developers should not hesitate to create some "application-specific layers" to enable cross-component application logic.

The following are some best practices we follow at BriteSnow (for more, see the brite documentation and the HTML5 application tutorial):