Saturday, March 8, 2014

Introduction Chapter from AngularJS Web Component Development by David Shapiro

The Problem...

In web development, we are now in the era of the "single page app".  We interact with fortune 500 companies, government institutions, non-profits, online retail, and each other via megabytes of JavaScript logic injected into our web browsers. While the AJAX revolution was intended to boost the performance by which content updates are delivered to the browser by an order of magnitude, a good chunk of that gain has been eroded not just by the massive amount of badly bloated JavaScript squeezed through our internet connections, but also by the increased amount of developer resources required to maintain such bloat. Most web applications begin life in the womb of a server rapid development framework like Rails, which hide the ugliness of request-response handling, data modeling, and templating behind a lot of convention and a bit of configuration. They start here because start-ups to Fortune 500 companies all want their web application to be launched as of yesterday.  Computing resources such as RAM, CPU, and storage are a cheap commodity in server land. But in the confines of the browser, they are a precious luxury. On the server, source code efficiency is not a priority, and organization is abstracted through convention.  But what happens when developers used to this luxurious server environment are suddenly tasked with replicating the same business logic, routing, data modeling, and templating on the client with JavaScript?  The shift in computing from server to browser over the past few years has not been very smooth.

Many organizations are finding themselves in situations where the size, performance, and complexity of their client code has become so bad that applications in the browser grind to a halt or take many seconds just to load, and they are forced to throw out their code base and start again from scratch. The term "jQuery spaghetti" is becoming quite common in the front-end community. So how did we get to this situation?

A Brief History of Front-End development for the Web

In 2005 "AJAX" was the buzzword of the Internet. While the technology behind updating content on a web page without "reloading" was not new, it was at this time that compatibility between browser vendors had converged enough to allow the web development community to implement asynchronous content updating "en masse". The performance of content delivery via the Internet was about to take a huge leap forward.

2005 was also the dawn of the server "rapid application development framework" (RAD) with RubyOnRails taking the lead followed by CakePHP, Grails, Django and many others.  Before the RAD framework, developing a web application might have taken months of coding time. RAD frameworks reduced that to weeks, days, and even hours since much of the heavy lifting was abstracted out by following a few standard conventions. Anyone with an idea for an Internet start-up could have their website up and be selling to the public in a couple weeks thanks to Rails and company.

In 2006, a JavaScript toolkit called jQuery hit the scene. jQuery smoothed out the sometimes ugly differences in behavior between competing browser brands, and made life for front-end developers somewhat tolerable. Developers could now write one JavaScript program leveraged with jQuery for DOM interaction, and have it run in all browser brands with minor debugging. This made the concept of the "single page app" not just a possibility, but an inevitability. Assembling and rendering a visual web page, previously in the domain of the server, was now moving into the domain of the browser. All that would be left for the server to do is serve up the data necessary to update the web page. The rise of jQuery was accompanied by the rise of a "best practice" called "unobtrusive JavaScript". Using JavaScript "unobtrusively" means keeping the JavaScript (behavior) separate from the content presentation (HTML).

Back in the 90s, JavaScript in the browser was once used to add a few unnecessary bells and whistles like image rollovers and irritating status bar scrolling, as well as, the occasional form validation. It was not a language most people schooled in computer science could take seriously. Now, it is not uncommon to have a megabyte or more of logic implemented in JavaScript executing in the browser.  Of course, this code became quite large and messy because established server-side programming patterns like MVC didn't always translate well from a multi-threaded, dedicated server environment to a single threaded browser DOM tree. Much of the bloat is a direct result of the "unobtrusive JavaScript best practice". Because all of the behavior related to DOM manipulation should be done outside of the HTML, the amount of code with hard binding dependencies to and from the DOM began to grow. But these dependencies tend to be situational making code reuse difficult and testability next to impossible.

A number of JavaScript libraries, toolkits, frameworks, and abstractions have risen (and fallen) since jQuery to help us organize and structure our front-end code.  YUI, Prototype, GWT, and Extjs were popular among the first wave. Some of these frameworks are built on top of jQuery, some replace it while adding their own classical OO patterns on top, and some make the attempt at removing JavaScript from our eyeballs altogether. One commonality among the first wave of JavaScript frameworks is that they were all created by, and to make life easier for, the serve-side developer. Extjs and Dojo were built on top of a classical object-oriented inheritance hierarchy for components and widgets that encouraged code-reuse to a certain extent, but often required a monolithic core, and opinionated approach to how web apps "should" be structured. YUI and Prototype were primarily jQuery alternatives for DOM manipulation. Each of these had stock widget libraries built on top.

Around 2010 or so, client-side development had progressed to the point where certain UI patterns were being described for or applied to the client-side such as Model-View-Presenter (MVP), and Model-View-ViewModel (MVVM). Both are somewhat analogous to the Model-View-Controller pattern which, for a couple decades, was the one way to approach separating and decoupling dependencies among domains of application logic related to visual presentation, business logic, and data models. The Struts library for Java, and the Rails framework for Ruby lead MVC from the desktop to the web server domain. Component architecture was another way of separating application concerns by grouping together and encapsulating all logic related to a specific interaction within an application such as a widget. Java Server Faces (JSF) from Sun Microsystems was a popular implementation.

The newer wave of JavaScript toolkits and frameworks, as well as, the latest iterations of some of the older frameworks has incorporated aspects of MVP and MVVM patterns in their component architectures. Emberjs, Backbone.js, Knockout, and a toolkit mentioned in a few place in this book called AngularJS are very popular as of this writing. Backbone.js anchors one end of the spectrum (least opinionated). It sits on top of a DOM manipulation library, usually jQuery, and adds a few extensible, structural tools for client-side routing, REST, view logic containers, and data modeling. The developer manages bindings between data and view. While Backbone.js is often described as a framework, the reality is that it is more of a foundation upon which a developer's own framework is built. In the hands of an inexperienced front-end developer, a lot of code duplication can grow quickly in a Backbone app.

Ember.js could be described as being at the other end of the spectrum (very opinionated). While Ember.js handles management of data bindings, it requires the developer to adhere to its conventions for any aspect of an application's development.  One commonality between Backbone and Ember is they have to run the show. You cannot run a Backbone app inside an Ember app, or visa verse, very easily, since both like to exert their form of control over document level interactions and APIs like deep-linking and history.

Closer to the middle, Knockout and AngularJS are both built around tight data-view binding (managed by the core) and can exist easily within apps controlled by other frameworks. AngularJS has more functionality in a smaller core, lends itself very well to creating well encapsulated UI components, and the AngularJS team, backed by Google, has announced that the development road-map will include poly-fills and full compatibility with the upcoming W3C web component standards. 

Reusable and well-encapsulated UI components are the key to getting the code bloat in large single page web apps under control without the need for a major re-architecture. Re-factoring a JavaScript code base bloated with jQuery spaghetti can start from the inside out. Architecting and implementing web UI components with AngularJS (and with an eye towards the emerging web components standard) is the focus of this book.

Why AngularJS?

AngularJS is a new JavaScript toolkit having been production ready since mid-2012. It has already gained a tremendous amount of popularity among web developers and UI engineers from start-up to Fortune 500. While adoption of most JavaScript frameworks for enterprise applications are driven by such factors as commercially available support, ability to leverage existing army of Java engineers, etc. AngularJS' grassroots popularity has been supported primarily by engineers with prior frustration using other frameworks.

If you ask any front-end developer who's drunk the Angular flavored Kool-Aid, including the author, what's so great about it, they might tell you:

"I can manage my presentation behavior declaratively, directly in my HTML instead of imperatively in a second 'tree' full of jQuery bindings."

"I can use AngularJS just for parts of my page inside my app run in another framework."

"Because AngularJS encourages functional programming and dependency injection, test driven development takes almost no extra time, and my tests have a higher degree of validity and reliability."

"I can create custom HTML elements and attributes with behavior that I define."

"Any developer who wants to include my custom AngularJS plugin in their page can do so with one markup tag instead of a big JavaScript configuration object."

"I can drastically reduce the size of my code base."

"It encourages good programming habits among junior developers."

"No more hard global, application, and DOM dependencies inhibiting my testing and breaking my code"

"I can get from REST data to visual presentation much faster than the jQuery way."

What this Book Is and Isn't

At a high level this is a book about the benefits of web UI component architecture, and AngularJS is used as the implementation framework.  This is a book about solving some serious problems in front-end development and the problems are described via "user story" and use case scenarios and solved via examples using AngularJS. This book is an "attempt" to be as current and forward looking that a book on rapidly changing technology can hope to be. The Angular team intends that the toolkit will evolve towards support of the W3C set of web component standards, which is in early draft. This book will explore the proposed standards in later chapters, so code written today might be re-factored into "web components" with minimal effort a few years from now.

While some parts of this book focus exclusively on the AngularJS toolkit, this is not meant to be a comprehensive guide on all of AngularJS' features, a guide on creating a full scale web application, a description of widget in the AngularUI project, or an AngularJS reference manual. The architectural concepts of UI components are applicable regardless of implementation framework or tool kit, and might help the developer write better code regardless of framework or lack thereof.