Single page applications UI performance considerations versus traditional web applications

Published January 19, 2020

Single page applications (SPAs) are something I built up a lot of experience with when I was in my previous job, specifically using Angular, but the same applies to any of the myriad JavaScript frameworks around today.

We would pitch SPAs to customers as being preferable to traditional web sites, for the reasons of them being: 1. Modern, and 2. Fast. Modern because it's just how things are done now, and fast because with all your code executing and your template rendering client side, you aren't transferring large amounts of data around on your page transitions.

There are other issues affecting SPAs that impact user experience (such as maintaining state persistence when transitioning between screens), but, right now, I'm going to focus purely on performance.

In reality, the speed issue is slightly more complex than that.

Software speed is a tricky thing, which comprises at least two separate considerations: Firstly, how fast your application actually does things, and secondly, how fast it gives some indication to the user that it is doing something.

Let's talk about each of these factors in relation to SPAs.

Raw speed and the HTTP request

As we used to tell customers, SPAs cut down on HTTP requests by rendering templates and and executing code on the client side. HTTP requests are slow and a serious problem in web application performance, so SPAs are faster because they do make fewer HTTP requests.

In reality, that's a bit misleading. Yes, SPAs do more client side. Yes, HTTP requests are slow and need to be minimised in providing high quality GUIs. But the assertion that SPAs use fewer HTTP requests is not generally true.

The code is client side, but the data is still server side, so you need at least one HTTP request to get it. However, usually, you have multiple pieces of data on the screen at once. And, usually, you use one HTTP request for each one.

Let's consider an example of a fairly standard GUI you'd expect to find in an enterprise application:

Grid based GUI example

On this page, we have quite a few different pieces of data.

DataAPI end-point
Department tabsGET api/departments
Role dropdownGET api/roles/{department}
Employees gridGET api/employees/{department}

See the problem now?

That's three different HTTP requests to populate the data on this screen. A traditional application might be doing more on the server and transferring larger amounts of data, but it's doing it all in one single request and will probably be quicker, because the additional data size is not that significant next to the overhead of opening several new HTTP requests.

So how do you mitigate this? The only thing you can do is to amalgamate all the HTTP requests into one, which means suddenly your API becomes very messy and monolithic. And even then, you're still only competitive with the traditional application, you're not really beating it in any meaningful way.

There isn't a good answer to this.

Perception of speed

As I mentioned earlier, the perception of speed can be distinct from how fast the application actually does things.

A traditional web application has a very well defined user interaction loop in the sense that a page loads, the user clicks something, the browser shows some kind of GUI to the user to show that something is happening, the screen goes white, then the page loads. It's not ideal, but it works. The user generally knows something is happening, because the browser knows the page is refreshing, and the browser communicates that to the user.

In a single page application, there is no page refresh, so the browser doesn't help you out. The user clicks something, but the browser doesn't know what that means in the context of your application, and it's up to your application to show that something is happening.

All too often, this gets ignored. The user clicks to transition to a new screen, and the screen might half load, but the grid isn't populated yet, and then two seconds later it gains data. For those two seconds, the user is confused - "what's going on? Is the page loaded? The grid is there? Is there just no data? and the confusion leads to frustration with the application.

The answer to this is fairly simple: the application needs to show loading spinners or similar whenever an asynchronous operation is taking place.

It's easy to mandate this, but less easy to test.

If load events are close to instant then the perception of speed isn't really a problem - the user clicks something and almost immediately sees a response. This is what tends to happen in testing, because test environments tend to be on quiet and often local servers without much data in them. Superficial testing rarely reveals performance problems, because test environments often aren't subject to the same real world considerations that cause performance problems in production environments.

Then the application is deployed to production where hundreds of people are using it and things that took a tenth of a second in testing is now taking three seconds in production. Three seconds isn't necessarily a problem, but it is a problem if you don't have that UI spinner showing the user that something is happening because it was never put in during development and it was never identified as missing during testing, because testing didn't reproduce the same situation.

So it becomes a question of how good and detailed-focused your developers are - whether they generally make the right design decisions without first needing testing to tell them what they should be doing. My experience was that this generally didn't happen by default, but we tended to rely on low-paid development teams that were based in Russia, or were staffed by students on work-placements in the office. As a result, I saw a lot of user interfaces that hadn't been developed with care, which were frustrating and confusing to use.

Conclusion

SPAs can be fast, but you need to be careful in making sure your architecture is conducive to speed.

It's too easy to end up liberally adding data to your screens and adding more and more separate HTTP requests to retrieve it, which end up slowing down your application considerably versus a traditional web application.

It's the responsibility of the developer to implement GUI to provide feedback to the user when the application is in the process of responding to their actions.

Slow applications with unclear responsiveness are extremely frustrating and confusing to users, and more consideration needs to be applied to these factors when building SPAs over traditional web applications.

Filed under: programming, software development, single page applications
'