single page apps
and
JS MVVM Frameworks
Mac Newbold
Vivint
UPHPU - 2013-09-13
Roadmap
A Brief History of Web Development:
How Evolution Has Changed
the Way We Work
What is a Single Page App?
Why switch to Single Page Apps?
Okay, so what are the drawbacks?
A few Case Studies
Discussion/Questions
Who am i?
I'm a long-time* PHP web developer
I work with an awesome team of developers
at Vivint, making mostly internal tools
(and we're hiring)
I'm relatively new to Single Page Apps,
but have quickly become very
attracted to their benefits
* Without giving details, I've been around
long enough to have experienced most of
the Web Dev history lesson myself
In The beginning
On the first day (~1974), Vint Cerf and others
created TCP/IP, joined years later by DNS,
and the ARPANET started to take shape
On the second day (~1989), Tim Berners-Lee
unveiled a crazy thing called HyperText and
introduced the HTTP we know and love
On the third day (1991), the gods* separated
the World Wide Web (WWW) from the
Telnet, FTP, Usenet, and Email
* gods of the Internet
Let there be light
On the fourth day (1993), the graphical
Web Browser comes onto the scene
with a browser called Mosaic
On the fifth day (~1996), the secret started
to get out to the general public, and things
like "weblogs" and search engines emerge
On the sixth day (~1997), modern web
development languages (like PHP3)
overtake Perl/CGI for dynamic content
The modern era
And on the seventh day, everyone rested.
And rested some more. Then took a nap,
woke up, and rested.
How many web sites do you know that
still deliver content in primarily the same
way we have been using since the mid-1990s?
Server-side generated dynamic content
Typically using a database like MySQL
HTML/CSS and some JavaScript
Sound familiar?
15 years of Web Dev
In about the last 15 years, there have been
some major trends, but the core really is
extremely similar to 1997.
We have newer versions of HTML, CSS, JavaScript,
web browsers, and internet-accessing devices,
but really it's usually done in about the same way.
Until XmlHttpRequest (XHR), later known as AJAX,
started becoming available as early as about 1999.
It came quietly, but has grown ever since.
Single Page Apps
As AJAX/XHR gained in popularity, we started seeing
a major reversal: instead of
"dynamically-generated static web pages"
we started seeing some
"statically-generated dynamic web pages"
This gave birth to something new:
serve simple static content and do all the
dynamic stuff with JavaScript.
In theory, you could run a whole app with
a single page load...
What is a SPA?
Single Page Applications (SPAs) are simply
a web app served up as a single HTML/CSS
page that performs all the cool stuff with JS
You've probably seen them every day: Gmail?
What other sites you use work this way?
Single Page App is a philosophy for building
web applications that seems to be the next
phase in the evolution of web developent
How are they made?
There are a few key characteristics that
distinguish the Single Page App style:
- One initial page load of HTML
-
Dynamic features via JS/XHR/AJAX
- Database interaction via web services
Many SPAs are built with a client-side MVC/MVVM
library or framework (Backbone, Angular, Ember)
Any web services can be used, but REST services
with JSON output are common and work well
Big changes?
These aren't your grandpa's web apps:
- Say goodbye to server-generated HTML
- Backend language agnostic
- Frontend can be plain JS or compiled to JS
- Apps usually driven by data and events
It really is a different way of thinking about
your application and its world.
Why use SPAs?
Different people do it for different reasons,
but I think it is usually a combination of these:
- Performance
- User Experience
- Decoupling/testability
- Easier to build/maintain
- Heavy JS lifting, lighter back-end work
- Easier to provide offline operation
SPA Performance
SPAs can improve performance in several ways:
Load time: 1 file each of HTML, CSS, JS,
static files not dynamic
Less data transfer: XHR calls only send
raw data, not HTML markup
Load distribution: dramatically less load
on your server, by distributing it to clients
Caching gets a lot easier and more beneficial
Spa User Experience
AJAX and SPAs have raised the bar for
user expectations:
Besides actually being faster, JS interactions
make apps feel more responsive
Immediate feedback on click
Smaller data transfer means faster responses
Better error handling, easier retrying
Stuff devs like
There are some great benefits for you too:
Decoupling of back end web services and front end
provides great points to insert unit tests
JS build tools like Grunt let you organize your JS
to be more modular, but still compile to a
single minified compressed JS file
Clean REST APIs make life better
Use TypeScript, CoffeeScript, Dart, NodeJS, or
whatever you choose, on the bulk of your app
Offline Operation
Try operating in offline mode with your typical
server-side generated web application...
With appropriate use of local storage and
decisions about how and when to sync
data changes with the server,
you can provide a rich offline experience
You can set up apps so that local data changes
affect the local view even before they're saved,
and when the connection is restored,
seamlessly update the server and local data
Potential Drawbacks
Anyone who tells you something is awesome
without telling you the not awesome parts
is trying to sell you something...
- More JS coding, less PHP/whatever
- Server-side MVC doesn't matter much
- Client side MVC/MVVM matters a lot
- Debugging JS can be harder
- Switching from the old way can be hard
But none of this is the end of the world
Making the switch
For a long-time PHP guy like me, it can be hard
to want to build a lot of JS and very little PHP
You'll almost surely want some kind of
JS framework like Backbone, Ember, or Angular,
and that has some learning curve
If you aren't accustomed to JS debugging,
you will be soon
And then there's the transition period...
Evolving your App
Most of us already have an app or site
up and running and need to transition
to the new style without major interruption
If you haven't already REST-ified your back end
services, you'll want to do that first
After that, I've had good success with gradual
replacement of old-style areas with new-style
components. Since they share the same
DB/backend, the data stays consistent
My SPA experience
I haven't been working with SPAs a long time,
and I was skeptical at first, but it has been
really good so far and I'm hooked
About 6 months doing SPA, transitioning
about 20 devs to a new way of thinking
Three live apps, another nearing completion,
amid a typical load of other maintenance work
We've tried a few different ways, and have
found some methods we really like
Case Study #1: Draft
Our first attempt. A small island of SPA in
a sea of traditional PHP-based application
Users use a map with various overlays
and a variety of tabular datasets
to examine geographic areas and
maintain a list of their favorites
We tried Backbone - not bad
It is definitely a library, not a framework
To the rest of the app, it's a single page
that makes some AJAX calls
Case Study #2: T.I.
Our first fully SPA app, and our first go with Ember
We wanted a full framework, and selected
EmberJS and it has been awesome
Client-side MVC uses observers to keep
the view in sync with the data models
EmberData has great stuff for managing
synchronization with the server side
Maintenance needs have been lower than normal
Case Study #3: Arena
This app needed the opposite transitional
approach: SPA with pieces of old-style
About 4 of the SPA views are an iframe of
the prior PHP version of the app, as we
build the functionality into the SPA
We've found that the two parts coexist
surprisingly well, and it was able to
go into production earlier than
if we waited to fully SPA it
Case Study #4: A.M.
Similar to #1, another SPA island in the
same PHP-based app, but with EmberJS.
Lots of drawing boxes on maps, and subdividing.
With a few attempts under our belts, the SPA
aspects have gone very well. Biggest snags
have all been map or mobile-related issues
we would have had anyway.
The project proceeded ahead of schedule until we ran into issues with Leaflet, and a few of the now-resolved pre-1.0 bugs in Ember.
Lessons Learned
At this point, we're happy with where we're headed
and we've learned a few things we want to continue:
- Use a framework like Ember or Angular
- Plan your APIs carefully before you start
- Build and test incrementally
We haven't been able to add it yet, but
we're planning to add CasperJS testing
for our front ends, and automated unit
testing for the services with Jenkins.
HOW TO SPA
So now how does one go about building
single page apps in the Right Way?
The secret is to apply back-end
techniques to client-side code.
On the server, we do MVC, and it is Awesome.
On the client, they call it MVC, MVVM, MV*,
but it's the same kind of thing,
and it can be Awesome too.
MVC/MVVM/MV*
MVC = Model, View, Controller
MVVM = Model, View, and "View-Model"
MV* = I don't want to argue with you
about the name and acronym
"View-Model" is a really odd choice to me,
but it connects the data (Model) with the
rendered output (View), like a controller.
How it all fits Together
Top to bottom:
View
View-model / Controller
Model
--- client/server boundary (REST/JSON API) ---
MVC or other web services provider
Database
In short, the client-side MV* is a lot like
your server side MVC, but getting data from a
web service instead of directly from a database.
MV* Tools
There are a plethora (yes, a plethora)
of MV* tools out there now.
I'll focus on The Big Three:
Backbone
Angular
Ember
Disclaimer: I'm biased, and am a beginner with them
Backbone
Backbone is a library (not a framework)
Key features: Models, Collections, Views,
some event handling sugar, and
some glue to bind it together
Drawbacks: Doesn't have everything a
framework has, but you can add on
Uses: jQuery, Underscore
Others in this category: Spine, Knockout
Angular
Angular (ng) is an MV* Framework,
probably most popular of all
Provides all the tools from the
models up to the views
Most bindings are done with HTML
annotation via custom ng-* attributes
Doesn't seem to have a strong
data sync/persistence back end
Ember
An "ambitious" MV* framework from
folks like Tom Dale, Yehuda Katz, etc.
Seems to have a more Rails-like approach,
and a stronger data sync/persistence offering
(part of why we chose it)
Used to get knocked for having poor docs
during the pre-1.0 days, but much better now
We have liked the strong structure it provides,
and find it works great if we use "the Ember way"
Paradigm shift
In addition to the Single Page App paradigm shift,
there is another similar shift when working with
a framework like Angular or Ember.
You're no longer building a page then
adding JS to make it more dynamic.
You architect a system, bind your data/models
to your HTML/view, and it runs itself.
These shifts seem to be the biggest hurdle
to the widespread adoption of MV* frameworks.
What now
What does the future hold?
I think we'll see much more growth of SPA and MV*
Combine them with responsive design,
and maybe a wrapper like Cordova, and
you have a very potent web/mobile app
Instead of web devs being back end guys
who can do JS, or HTML/CSS guys
who can do JS, you will see more and more
hardcore JavaScript developers
Change can be good
Overall I think we're headed in a great
and exciting direction, but there are bumps
Jumping in with both feet was probably
the number one thing I think we did right
when we adopted this methodology