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.
No comments:
Post a Comment