In a previous post we talked about client side and server side web architecture. We showed the difference between the two approaches and concluded that client side web architecture offers a lot of benefits. Now it's time to get our hands dirty and put theory into practice. In this post we’ll compare both approaches using a real application.
The demo application is a basic Facebook-like app. The main page is the Dashboard. Here you can find installed apps, upcoming events, messages and a news feed. There is also a Friends page where you can search for specific people in your network.
I've implemented the same application twice. For the first version I used a server side web architecture and ASP.NET MVC as a framework. The second app was built using a client side web architecture with AngularJS and ASP.NET Web API. The backend for both applications is the same. The overall architecture looks like this:
We’ll compare the behavior of both implementations while performing the following three tasks:
Chrome Developer Tools (F12) will track the network traffic.
SQL Server Profiler will show us what happens in the database.
Let’s take a look at what happens under the hood of our website when we browse to the Dashboard.
First up is the MVC application. This is the network traffic:
I’ve left out resources that are cached by the browser (like scripts and stylesheets) because they don’t cause any network traffic. We see that the browser made a single request to the server. The response contains the HTML of the entire dashboard page, taking up 2.2KB.
Let’s compare this to the AngularJS application:
This time the browser makes four requests to the API of the server. Each response contains the JSON data of one of the four data blocks - news feed, messages, events and apps. Combined, there’s about 3.2KB of network traffic. Note that the HTML does not need to be fetched. Since I’ve visited this page before, the HTML is already cached by the browser.
Looking at the database traffic, there is no difference. Both applications cause four SELECT queries to retrieve the data.
For this action, server side architecture is outperforming client side architecture. There are fewer requests and there’s less data going over the wire. All hail and victory to server side architecture?
Not so fast.
Here’s the thing: client side architecture is very cache-friendly. Using an API enables you to cache resources close to the client, by caching the HTTP response. This means very little code is executed server-side. You can take things even further. The server can tell the client that the resource it requests hasn’t changed using ETags. The browser can safely use its own cached resource. This reduces the amount of data going over the wire. It’s as fast as lightning!
Let’s apply this to our example:
Resources like apps, events and messages rarely change and can therefore be cached server-side. When a user browses to the website, only the news feed needs to be fetched from the database. For the other 3 requests, the server returns a 304 – Not Modified. The browser can retrieve the data from its own cache and no data is transferred over the network.
The best part: only a single database query is executed! This is the one retrieving the news feeds.
Can you use caching with a server side architecture? Of course you can, but it will be at a lower level. There wil still be some overhead due to code executing at the server, for example serialization. In addition, the data will always have to be transferred over the wire because it's contained in HTML.
Let’s try something else: posting to the wall. Looking at the network traffic of the MVC app, we see that the browser makes 2 requests. The first one sends the new wall post to the server. The response is an HTTP 302 - a redirect to the second request. This request retrieves the entire HTML of the resulting page.
This behavior is reflected in the database traffic. First, a new post is created using an INSERT statement. Next, four SELECT queries are executed to construct the HTML of the resulting page.
Let’s compare this to the AngularJS app. This time the browser only makes a single request. It sends the new wall post to the server. The browser knows that the apps, events, messages and other wall posts haven’t changed. It can add the new post to the Wall itself by modifying the HTML (DOM manipulation). No additional network traffic is needed.
At the database level, there's only a single INSERT statement. There’s no need for any SELECT statements, because the browser already possesses the data. One query instead of five? That's great! Now imagine a thousand users posting to their wall, and you start to get an idea of the resources you could save.
Imagine there is a delay in fetching the Events from the server, for example due to a database lock. We’ll simulate this in our app using a Thread.Sleep of 3 seconds in the Event repository.
Let’s take a look at the impact of this delay. In the MVC application, the browser has to wait for the server to return the HTML. This happens after all necessary data is retrieved. It will take the server at least 3 seconds to return the page. Meanwhile, the user is looking at this:
The user interface is blocked and there’s nothing left to do but wait.
In the AngularJS app, the browser is able to retrieve apps, the news feed and all messages without any delay. This is what the user will see:
He probably won’t even notice the events are missing. These will show up after 3 seconds. In the meantime, the user can already start reading and even write new wall posts.
[vimeo 127007320 w=720&h=407]
The use of JavaScript opens up new ways to interact with your users. Imagine adding a notification panel with a nice sliding effect. Or searching for friends, with search results updating as you type. No need for a button and no need for a page load.
We can show a pop-up to send a message. Or use autocomplete to search for contacts. These are just some examples of rich UI components. There are many more! How about an interactive grid, or a chart?
Some rich UI components can still be used with a server side architecture. Lots of applications out there combine a framework like ASP.NET MVC with a little bit of jQuery and Bootstrap. However, you will still need page reloads and you're missing out on some great features like two-way data binding.
By now you are hopefully convinced that client side web architecture offers many benefits. To wrap up, here are the most important advantages.
Happy users
Rich interaction, dynamic components and a fast web app. This is how you win the hearts of your users!
Save on infrastructure
Efficient use of resources leads to better performance. There will be less need to scale and you can save money on infrastructure. As more and more tasks are pushed towards the browser, the load on the server is reduced and the app becomes more scalable.
Reusable API
You can make your API available to other user interfaces than your website. A mobile app? An IoT device? They can all use the same server! You can even make money by selling the access to your API to third-party developers.
How about the downsides? As mentioned in the previous post, you will need to take into account the different browsers and their versions. However, there are plenty of libraries out there to help you deal with browser peculiarities. In addition, the granular approach of client side architecture can sometimes lead to chatty interfaces.