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
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.
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!
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:
- Implement rigorous unit tests via Jasmine which is run automatically as part of our continuous integration
- Implement code reviews to ensure proper coding practices
- 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
First request (no cache) takes 18.6 seconds to complete.
Second request (with cache) takes 8.3 seconds to complete.
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!
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!