On single page apps
Wednesday, December 28th, 2011 at 1:31 pmTL;TR: Single page apps are coming and necessary for the web to be an apps platform. We have to battle two main issues: old conditioning of users and sloppy development for the sake of doing something “new”.
At the Smashing Mag meetup in Stuttgart Paul Irish got a question about single page apps and what he thinks of systems like backbone.js and client-side templating. He quoted somebody of Sencha who famously said that if he sees a web site with an empty body tag he is very happy (citation needed, help me). Paul explained that his first reaction to this was disbelief but he started thinking much more about it later on. He then proceeded to show the Google mail blog which is a single page app that has no real HTML source but instead is a small JSON object with client-side rendering to HTML using JavaScript.
All of this made me go “why” and “meh” mostly, but then again, I am old, seen a lot of things fail, had to fight for sensible use of Ajax without breaking conventions (without giving it yet another name like hijinks or something like that) and learned all I know about the web from a web of view-source and links that can be opened in multiple windows and tabs.
But I also am a very firm believer in the web as a media evolving and seeing how web usage patterns change with new consumption devices I am very much aware that there is a need for single page apps.
Why single page apps?
The benefits of single page apps are obvious:
- The first load sends you the shell of the app and it stays in the browser – this means it can be a very quick experience
- Subsequent data loading can be done by sending very small JSON objects containing content which is great for traffic-limited or slow connections (i.e. mobile environments)
- Maintaining everything in JS means you don’t need to have several, specialised developers on the project
- You replicate best practices of the backend and “higher languages” – especially MVC - on the client, thus making it easier for developers who are used to that to build web apps
- The experience is sticky – you stay in one interface and load content into it which is what “real” apps do
In essence, all of this is about a snappy interface. You don’t send much data, and you don’t have a reload and interface refresh in the browser.
It is nothing that new
Paul reminisced about the web interface of Outlook which out of a sudden told him that there are new emails to be read without reloading (the birth of XHR which lead to Ajax). I had seen this before XHR in forums and boards by having a frameset and an HTTP meta refresh. Frames in general did a lot of what we are craving with single page apps: we loaded only chunks of data and kept the main interface static on the screen.
The old problems of single page apps
The drawbacks of single page apps are the same we had every time we intercepted the reload of the page starting with frames, then with Flash and later with Ajax. Most of them can be done with native APIs these days (history API is a life saver in this case) but the issue is that we are breaking conventions. People in the past have been conditioned to expect things on the web to work in a certain way:
- We compete with a lot of useful browser features that we need to simulate:
- History navigation
- Preventing wrong loading by hitting the stop button or ESC
- Loading indicators – is something happening?
- Bookmarkability
- Ability to open a link in another tab
- State retention. When I reload the page I should get back to where I was and not the initial state of the app
- Timeout detection (browsers tell me when something took too long)
- Printability of pages (I just printed out a wikipedia entry for my mother)
- If we don’t change the URL and keep the state of the page we break the web:
- Sending a link to a friend should get them where we were (unless it is our data behind a login of course)
- A search engine spider should be able to index the content
- Conversion tools should be able to get the content and create more accessible versions
- Slow connections should at least deliver a partial experience. When being on a bad connection (as I am now) I should be able to reload and get more content once I get stuck. I can use gmail even on the flakiest of connections as I can switch to an HTML view and hit ESC when it gets stuck
None of these are insurmountable issues, but it is very easy and tempting to forget about them. This is why we had headless players and redirection scripts in the case of Flash apps. We should be aware of these already solved problems and implement them as a base of our UX considerations.
A shift in the way we use the web
A lot of these interactions above are used by people who have been on the web for a long time. Endless scrolling seems odd to them, they want to see a scrollbar and know how far the page goes. People who started the web on a touch interface or a mobile device on the other hand are confused when they have to click buttons or see a pagination. The old folk of the web have an email client, a browser, maybe a picture viewer and a very sorted download folder. The new folk do all of that in Facebook in a browser and are very happy to never see the page reload or having any of that content on their hard drives.
So to a degree I think it is important that we understand that some of the practices of old are just that – old and possibly outdated. For new users a page reload is as much a confusion point as scrolling and not getting visual feedback that something is loading until it appears is for the old-schoolers.
The new problems of single page apps
That doesn’t mean though that there are no issues with single page apps and a web without reloads. There are quite a few things we have to consider even if we say we build for the new generation of web users exclusively or within a fixed environment.
The first thing is that we are promising a fast web of awesome that is always available and every button does something to the app you are in. This means we need to come up with UX patterns that work with a variety of users and environments. It is not easy to compete with native apps – if we take on that challenge we should excel in it and not do it half-baked.
The second issue is that the web as we have it now is full of bad code. This is especially the case when you rely on third party code without having access to what it does. Unless you run a paid-for app, you will show ads. This is how we work and it is a broken, outdated model. Ads count page views and clicks so you need to find a provider that is OK with you auto-refreshing an IFRAME or something similar. But I deviate from the main point: if the ad code throws an error your whole app could die with it.
It doesn’t even have to be third party code. I can see sloppy code without error detection and fallback being advertised as “teething pains” these days. This is not true. We went through the process on non-reloading interfaces a few times already. A lot of omission of simple condition checking and error messaging is either arrogance or inexperience. As Zach Leatherman put it yesterday arrogant statements like “All of my JavaScript code and 3rd party code won’t have errors, so I can ignore Progressive Enhancement” will come to haunt you as the screenshot of Klout shows:
Gawker also had that issue and Mike Davies has quite some information as to why relying on JS for your links is an architectural nightmare.
In short – we will now once again face a time of New vs. Old and people building apps seeing their own setup and experiences as those of everyone on the web. We had this with Flash in the past and we had it with Ajax. Now we’ll repeat the long discussions, endless bickering and using technology and interface patterns for the sake of using them instead of where they are needed.
Case in point is the blog mentioned by Paul. I am sure it was used as a testing platform for the single app container of Google. Personally I think there is nothing dynamic in a blog that would really warrant it being an app. Not everything on the web needs to be a new Facebook, Google Reader or Google Mail.
Personally I am happy to load a page and read an article in another tab while it is loading and coming back when the tab tells me it is ready for me. I like my web multitasking. On a mobile device or tablet this is a different issue. But who says that this experience should also be forced upon me when I have lots of space, tabs and a browser that brings me the whole web instead of a single resource?