Post navigation

I created two identical web applications: Long Live RSS! – Classic Web Edition (CWE) and Long Live RSS! – SPA Edition (SPAE). Both are virtually identical applications, except for the client-side implementation. CWE delivers the page with a simple HTML and CSS combo. SPAE employs Angular to present the application as a single-page application.

In this article, I’m comparing the performance of the two applications as observed from a user’s end.

Note: By the time you’re reading this article, I may have updated the applications and the result of the runs may have been affected.

For both applications, I did the following series of actions as my test cases.

Table 2 indicates that, cumulatively, SPAE has lower number of requests. CEW has a higher number but browser cache prevents CWE from hitting the server for every single request. When considering cached responses, CWE hits the server only 64 times–less frequent than SPAE (69 times). Table 2 also shows that CWE transfers slightly fewer bytes and in a slightly shorter time.

The following are some details about the test runs.

The two applications are hosted at a2hosting.com.

The two applications shared one instance of database.

I did the following before each run

Refresh data

Warm up the server

Clear browser cache

Open a new instant of Chrome’s incognito window

Content displayed came from my database, except images in the articles

Developing a web application using a framework such as Angular or React has been the norm nowadays. When you use one of those aforementioned frameworks, you typically create a so-called single-page application (SPA).

Typically, developing a SPA is more expensive because it involves more client-side development (using JavaScript or TypeScript) and still yet similar amount of development on server side. In this article, I’m looking closer at the cost of developing a SPA vs a classic web site.

I created two web applications: LongLiveRss! – Classic Web Edition (CWE) and LongLiveRss! – SPA Edition (SPAE). Both applications are of the same functionality: a feed reader with identical UI and features such as reading feeds, saving an article to your favorites, etc. The two applications differ mainly in the client side implementation. One utilizes SPA technology (Angular), another is a classic web site rendered with HTML and CSS (no JavaScript).

Long Live RSS! – SPA Edition

The following is the technology stack employed to build the two applications.

CWE

SPAE

ASP.NET Core MVC 2

ASP.NET Core API 2

MS SQL Server 2017

MS SQL Server 2017

Bootstrap 4

Bootstrap 4

Angular 7

The two applications share (either the code or the instance) several libraries: Services and Repositories libraries. Both also share the same instance of database. Diagram 1 shows how the data flows from the database to the view rendered by a browser. The components with grey shading indicate those with shared instance/code.

Diagram 1. Data flow in CWE vs. SPAE

The cost to develop an ASP.NET MVC Controller is similar to that of an ASP.NET API Controller. A lot of code (such as ViewModel definition) can potentially be shared between the two. A Razor View looks a lot different than an Angular View, but the complexity is about the same.

The diagram shows that both applications employ similar components except that SPAE includes a component which has no counterpart in a classic web site: an Angular Component. The extra cost of developing a single-page application lies on this part.

Two Applications in One

I own a 1,017-page Pro ASP.NET Core MVC 2 book. I also own a 788-page Pro Angular book. A hasty estimation suggests that building a SPA costs 177% more than building a classic web site. More accurate estimate will require analyzing the complexity of server- and client-side code. Angular packs a lot of features that you can’t master overnight. It’s an opinionated framework which also requires somewhat advanced understanding of software design.

When you build an Angular-based SPA, you will write a lot of Angular code, so much that it feels like developing two applications. The Angular code is a big part of the application. Angular framework usage in a web application is rarely a (progressive) enhancement to a classic web site unlike the usage of jQuery in recent past. When a browser doesn’t support JavaScript, a SPA will become unusable, while a classic web site with jQuery will (should) degrade gracefully.

Do Everything (Not Really, but Many Things) Twice

In SPAE, many application infrastructures implemented on the server are done as well on the client side. Some examples are routing, authentication, and error handling.

Routing

When a visitor visits, say, http://example.com/favorites, you need to program the Angular routing module to route that request to the correct Angular Component. And when an Angular service sends a request to the server at http://example.com/api/favorites, you need to map an ASP.NET API method to handle that request.

Authentication

Your Angular code needs to determine if a visitor has access to a certain view and handle it accordingly. Similarly, certain methods of your ASP.NET API needs to be protected from an unauthorized access.

Error handling

Inevitably you will write some sort of global error handler for your ASP.NET API. The Angular code will also need to handle error returned by the ASP.NET API or raised by some other Angular code.

Extra Work With Angular

Handling the back button used to be a lot of effort in a SPA. Nowadays, Angular handles that for you behind the scene. Plenty of things, though, come free with a classic web site, but still needs to be (re)implemented in a SPA.

Loading Progress Indicator

When a SPA sends a request to the server, there is no progress indicator shown by the browser while waiting for the response. You have to write your own implementation or incorporate many available packages out there.

Data Consistency

SPAE consists of different areas on the view. When data is updated in one subview, you have to program certain routine so that different subviews which reference the same data reflect the latest value.

Client-side Code Payload Size

When accessing SPAE, the browser has to download a lot more client-side code. (I analyze more of this in part 2.) Hence, optimizing the size of all those static JavaScript files is a complexity that a classic web site doesn’t have to deal with.

I took the three “To Do” apps built with Angular (version 6.0.3), React (version 16.4.1), and Vue (version 2.5.16), applied some form validation, and generated a production build for each app. In this article, I’m comparing the build size and the payload size of each app.

Framework

Files Generated

Number of Requests

Payload Size (KB)

Angular

7 files (290 KB)

5

284

React

9 files (1.98 MB)

4

406

Vue

8 files (962 KB)

4

180

Table 1. Build artifacts and payload summary

Files Generated are the files produced by the build process and the ones to be deployed to the production server. React and Vue have a lot larger total file size because the build process of the two frameworks produce a .map file for every minified JavaScript file and/or CSS file.

Once the app is deployed to a production server, accessing the app on its URL triggers requests to several static resources (JavaScript, CSS file, etc); these requests are Number of Requests on Table 1 above, excluding requests to remote API.

The Payload Size is the total size of all those static resources. JavaScript files (the framework and application code) makes up the most of payload. The React app has the most payload, and Vue app the least.