Everyone’s building single page applications (SPA) these days. We’ll take a look at some of the challenges and best practices for building JavaScript heavy applications. Some of the things might not be so obvious at first glance, but it definitely helps to think about this up front. After all, it’s quite a big decision to go JavaScript all the way.

Don’t break the browser

While most of the modern JavaScript frameworks out there can handle URLs pretty well these days, it is still important to sit back and think about this for a moment. Your application might have multistep forms, which aren’t persisted in the URL, but the user might still want to reload the page without losing everything.

There is usually a lot of state on each page of a Single Page Application. It might be pagination, or the amount of scrolling the user has done when using infinite scroll, or the detail of something that appeared in a lightbox when he clicked on it. Such things usually lead the user to another page when using a regular website, but in a Single Page Application, it usually doesn’t. Even though the user would still expect the state to somehow be perserved.

Test on real mobile devices

Everyone has at least one smartphone these days, or a tablet, or a small laptop with a touch screen. The point being, no matter how small your audience is, they will try to use your application on their mobile devices. I’m saying try to use, because if you haven’t thought about mobile in the beginning, there’s a fair chance that the app won’t work very well. The reason why this is a problem more for Single Page Applications and not for the old-fashioned static websites, is that the more JavaScript you have, the more likely you’re going to run into something funky.

The mobile browsers are pretty good at displaying <a href="..."> links, but they might not be so perfect at drawing your fancy charts, or at handling that parallax scrolling you just added using 5 different hacks. In fact, scrolling is probably the most absused thing I’m running into. It just always feels that I’m either using a mouse on what was designed for a touch screen, or the other way around. Just because you’re developing on a MacBook Air with a Trackpad, it doesn’t mean that everyone in the world uses a Trackpad as well.

An important thing to note here is that testing on a real device is not the same as resizing your desktop browser window to 480x360. There is a completely different feel from using your fingers to move around.

SEO

If your application is facing the public internet, it should be indexable by the search engines. Imagine if something like Amazon suddenly decided to rewrite everything using JavaScript. It doesn’t even need to be a Single Page Application, all it takes is that the main content is generated by JavaScript.

A great example of this is Discourse, which while being a Single Page Application written completely in Ember.js, still manages to work without JavaScript at least to some extent. This is not only good for the search engines, who can easily index the whole forum, but also for users on old mobile devices, or just bad browsers in general. In fact, I know quite a few people who have JavaScript disabled by default, and only enable it for the sites they trust.

I’m not really talking about progressive enhancement, since that would take a lot of effort on your side to make the application work completely without JavaScript after you’ve decided to write the whole thing in Angular. What I’m saying is that it is a good idea to have the core functionality working, at least to some extent, without JavaScript. This might mean that the users can read the content, but can’t do anything else on the site.

SPA users have higher expectations Once you start with the whole SPA thing, your users’ expectations will grow massively. Take Discourse for example. If you’re replying on a regular forum, you simply hit the reply button and start writing your reply. If something pops up in your mind and you decide to search the forum some more, you simply open a new tab in your browser.

On the other hand, Discourse implemented this neat feature when you can keep navigating the site, while having your reply still open at the bottom of the page (see this topic). This however, while being an awesome feature, brings up a lot of newborn complexity. For example, they’ve also implemented a feature, that if you finish writing your reply while being on a different topic than you were originally, you will be prompted to reply to that topic instead.

screenshot

You can also collapse (minimize) the reply form, it saves the text as you type to the backend, etc. Just a bunch of very cool things from a UX perspective.

But there’s a downside to this as always. Think about how much work goes into designing the workflow I just described, vs creating a simple and static HTML form. It isn’t even on the same scale. You can deliver a much better experience to the user, but you’re also going to delay the whole project by a significant amount of time. Ever new feature will yield 10 new opportunities for making the UI better (and more complicated), and in the world of client side applications, that also means it will take more time.

Another simple example here might be file uploads. If your website has a regular file upload, the visitor can simply drag & drop a file to the input and press submit. If it is a JavaScript application, you’re probably going to use the HTML5 File API to get to the file, then maybe add a nice overlay to show that the area responds to the user dragging a file, then maybe display a progress bar of the upload, which will require some backend work, then you’ll decide to add some animations to make it look good. Sure the JavaScript version might be cooler, but it will also take you a week to do properly.

Do you really need a Single Page Application?

Before you actually get into building one, really think about what parts of your application need to be highly interactive. It might be the case that there is only a single page in the whole app that would benefit from being all JavaScript, while the rest can easily be just plain old HTML. If this is the case, you might realize that there is no need for a client side router, since all the logic is on a single page.

By limiting the amount of pages that are pure JavaScript you can focus all of your effort into making those that are really great. There is really no point in wasting half of your development time on making the about/help/docs/pricing pages, when you could be working on your core application instead.