Single Page Applications

We had a new co-op start on our team yesterday, and I was trying to google some introductory articles to some of the technologies / design patterns / other things our team uses to help him get acquainted. There were a few subjects that I couldn’t really find any “introductory” material on, so I’m going to do my best to fill the void. Today’s topic: Single Page Applications!

The Before Time

So a bit of web dev history to start off with. Right when the web was in its early days, it started off as static documents with hyperlinks. This was great – it provided a whole new way to navigate through information, and is still the basis of what the internet is today. The downfall was that it wasn’t very interactive – there was no way for a user to send data TO the server, it was only possible to request data FROM the server.

To combat that, people introduced the concept of a Common Gateway Interface (CGI). The idea here was you could fire off any app / process you wanted and it would be forwarded the input from the user’s GET or POST query, and your application would be responsible for delivering an HTML document back when it was done. So began the era of server-side web development.

This was mostly done in Perl at first, as most of the web servers were *nix machines and server admins were already familiar with Perl as a shell language. But Perl is a shell language, mostly targeted at string manipulation, and wasn’t really suited to handle the needs of web development (at least at that time). Soon afterwards spawned more web-development-centric languages like PHP (1994), ASP (1998), and even JSP (1999) were created and integrated with web servers.

Static Documents are for Suckers

Meanwhile, a few smart people noticed that although we have a full input/output stack, we’re still serving up static documents as a result. JavaScript was created to allow developers to execute code on the user’s side of the equasion, and work on Dynamic HTML / the Document Object Model was started shortly afterwards. With all this in place, web developers were now allowed to create dyanmic documents that could respond to the user’s input without having to ask the server for a brand new page every time.

There was one more big usability flaw in the web – the “reload”. Every time you performed an action on the client that required new data from the server, your browser shows a blank screen with a tiny loading indicator, and you sit patiently while you wait for the server to give you an entirely new document. So smart people came up with Asyncronous JavaScript And XML (AJAX), which allowed clients to ask the server for snippits of new data or document in the background.

To support this fancy new AJAX stuff, Web Services started to come into their own. Web Services provide a platform-independent way of sending and receiving data from a web server. All you have to know is the format of the data and how to make a web request, which by this time almost every programming environment provides for you. Pair a web service with an ajax request, and you can have random puns on any page you want!

The Browser Arms Race

So now that JavaScript is actually useful with DOM manipulation and AJAX, browsers had to start playing catchup. They’re no longer just responsible for rendering static HTML documents, they have to be able to support dynamic UI changes at a whim and have a really complex network communication model. Browsers started working on their game. IE6 was the first browser to really support all of these scenarios for a long time, hence the reason why so many web apps were tied to it. But then Firefox stepped up and set a new bar, and shortly afterwards Chrome decided to show everyone how JavaScript should be handled. The end result is we have some damn powerful client software running on almost every web client.

The Modern Age of WebDev

That brings us to today, the “modern age” of web development. There are still a lot of web applications that are using server-side rendering, which has been the defacto way of doing things for the last 19 years. If you think about it, a server-side web application is really just responsible for creating an HTML document. All that horsepower, all those server web farms, and all they’re really doing at the end of the day is making an HTML document. You know what else is good at working with HTML? The browser! We’ve sunk TONS of resources into making our browsers super powerful, particularly at creating and manipulating HTML. Why not take advantage of that?

So began the idea of the single-page application. The general idea is that you make the client browser do everything, and rely on web services for data. During the initial web request, your web server sends the client a static html page, any resources it needs (css, images, etc) and a bunch of JavaScript. From there, the client executes the javascript and “creates” the web application UI. Odds are that client JavaScript is going to make some AJAX requests to a web service for some data and use that to create the elements on the page.

Another main concept of single-page apps is a lack of page navigation, at least in the traditional sense. If you click to go to an item’s details for example, what will probably happen is the JavaScript will hide the element you’re currently working in and show an entirely new element, probably loaded with some data from another AJAX call. There’s no page refresh, no blank screen waiting for the server to do its thing, just a smooth user experience. If you’re super fancy there might even be a nifty jQuery UI transition between the states!

Why SPAs?

There’s quite a few benefits to single-page applications that you just don’t get with server-side web apps. The first and most obvious is user experience, which comes in many forms. On initial page load, because your server is serving up static documents, there’s a very small load time – it just has to read everything from disk, it doesn’t have to worry about doing any processing or looking up any data. That being said, your page will be pretty much empty at this point. Which is fine, and leads me to my next UX point – loaders.

Because all data transfer after the initial page load is done using AJAX, you have complete control over the loading experience. If a user clicks on a button to send data, you can immediately show a loading graphic (of your own design) while you wait for your web service to process the input and return a response. This is 1000x better than the traditional “blank screen w\ loading gif” approach that most browsers use now. Even if your AJAX calls would take just as long as a page render on the server, you still provide a better loading experience to your users.

My favorite benefit of SPA’s is the segregation of server and client responsibilities. Your server, that expensive piece of hardware that you’re paying those terrible hosting costs for, is no longer wasting cycles generating HTML – it deals purely in data. Any request to your web service for an operation or data returns JSON or XML (or whatever format you choose), that’s it.

An additional benefit of this approach – you have an API now. Not only can you make your web application, but when you get crazy big and want to expand to iOS or Windows 8 or any other platform you don’t have to worry about rewriting your server-side, you just have to make a web request. If you wanted to do that with a traditional server-side MVC language, you’d either have to do a lot of string manipulation to parse out the HTML or code something alongside your MVC app, which is extra work that you just don’t have to do with a SPA.

Why Not SPAs?

There’s a few drawbacks to this approach however. There’s a very heavy reliance on JavaScript and powerful client browser software, so a device that doesn’t have a good JavaScript engine (i.e. older smartphones & browsers) may have a terrible experience on your app (or none at all!). Also, because your initial page load is essentially a blank HTML document, search engine browsers don’t really do well at indexing your page. Arguably this isn’t an issue, as your web app should probably be loading user-specific content anyways, but it’s something to keep in mind.

The other major thing is most of today’s browsers don’t really work with the SPA navigation concept – if a user clicks back in the browser, they’d go to the page before the initial page load, not the last navigation they performed in your web app. There’s existing scripts and upcoming changes to address this (HTML5 history manipulation), but until then it’s a bit of a shift for end users.

All in all, SPAs are a great idea for web applications where you’re showing user-specific content. My rule of thumb is if you have to log in, you can probably do it as a SPA. If you’re creating a content-based or general knowledge website, like a blog or news site, you probably want to stick with server-side applications.