Menu Home

Under the hood: How the user portal was rebuilt

Over the last 6 months, the web team had been hard at work rewriting the user portal from scratch. We have finally finished it last month and are proud to launch it to our users. The upgrade was not just limited to the UI and it’s loading speed – there were also numerous architecture and security upgrades. Read on to find out more.

Why the rewrite

Our previous user portal was written in GWT and had undergone major design and focal changes over its two year life-cycle. Because of it’s single page design, the portal had to download all page components before the page could be rendered. This resulted in a relatively long wait before the user could interact with the page. On the plus side, once the portal was loaded, it was almost as responsive as a native application.

The multiple rounds of changes also resulted in severe code degradation. We noticed that maintenance was starting to become unmanageable and feature addition took far more resources than it should.

What we changed

Architecture

Our implementation with GWT had a very tightly coupled client-server architecture. Requirement changes often involved updating both server and client code. As our application server only acts as a proxy to our actual API server, we decided to simply discard the server side logic entirely and to rewrite our portal using HTML and Javascript: instead of fetching the generated page from a Tomcat application server, we serve a plain HTML document and populate user content via AJAX calls to our API servers. This had a two-fold benefit: (1) it eliminates a round-trip-time to and from the proxy and (2) we no longer have to bother with writing the API wrappers for our application server.

 architecture1

Following in the footsteps of our apps team lead, we decided to rewrite our portal using Backbone.js, and use Require.js to optimize our project. By adopting this approach, we could test any code changes easily on our browser without the need to start up any servers. As our client side architecture is very similar to what the apps team had done, we will omit the details here.

Code Partitioning

A major factor in the decision to rewrite was to improve the maintainability of the code. At the end of it’s lifespan, the old user portal had more than 50,000 lines of code. In rewriting our new user portal, we needed to modularize our user portal into sub-modules – each module with it’s own repository, unit tests and continuous integration. The goal was to allow deployment of any module without the need to bring down the whole user portal for maintenance.

We tested the feasibility of this approach by replacing login/registration logic with our new Auth module and the transaction logic with our new Transaction module. The upgrade greatly improved the loading speed of the login page (from around 10s to 1s!) and was a big functional improvement to our transaction module. With our initial successes, we proceeded to rewrite all other components of the user portal.

Our modules are distinguished from apps by how they perform authentication. Our modules use a shared login cookie for API authentication while our Apps uses OAuth for authentication.

Caching User Data

We wanted to further improve user experience by reducing page load speeds. To do that, we decided to cache some non-sensitive data (e.g. installed app list) to give the perception of a quick loading speed. To ensure that what the user see is up-to-date, we load and update user data in the background after it (the cache) has been rendered.

We were surprised by the effectiveness of this simple strategy: instead of showing a loading indicator for a 1 or 2 seconds, the user would see all most of his user information instantly after the page has loaded!

Reliability

The frequent code updates and the lack of proper testing resulted in frequent bug reports – which required bug fix deployments. This usually meant a few minutes of downtime for the server restarts. Additionally, the server may suffer memory leaks or errors and fail catastrophically.

We adopted several approaches for this:

  1. Implement rigorous unit tests via Jasmine which is run automatically as part of our continuous integration
  2. Implement code reviews to ensure proper coding practices
  3. Do away with the server and instead host our entire user portal in Amazon S3. This may seem odd, but this allows us to easily serve our website from the cloud via Amazon Cloudfront. By eliminating the need to maintain our own application server, we have reduced our portal’s point-of-failure to just Amazon (which has very high reliability).

The result is a system that is agile and robust. Deployment is just a single click in our Continuous Integration system – which automatically runs the Jasmine test suites before syncing the files to our S3 bucket. Another benefit is that any user using the system will not notice the deployment because his session will not be interrupted at all.

The fact: Speed comparison

We compare the speed difference between the old portal and the new portal, both loading the company account manager. Our machines are located in US and we are conducting our tests from Singapore

Old Portal
First request (no cache) takes 18.6 seconds to complete.
Second request (with cache) takes 8.3 seconds to complete.

New Portal
First request (no cache) takes 8.5 seconds to complete.
Second request (with cache) takes 3 seconds to complete.

The speed-up is significant – almost a 300% improvement in loading speed for a returning user!

Final Words

We hope that our users are satisfied with the improvements in our new user portal. We will be continuously adding new features and improving user experience. Let us know if you have any feedback for us!

Categories: Company News

Hoiio

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: