Since day one at Altocloud we've placed a huge importance on building a product that will scale as we grow the company. We are fortunate to count web performance guru Steve Souders as one of our advisors and his ongoing guidance has been extremely beneficial to our team. Over the past few months, we have been making significant enhancements to the structure of our web application, having expanded the scope of our previously-segmented Agent and Admin applications, into a single User application.
Furthermore, the size of the Altocloud team and customer base has been increasing rapidly, and we quickly needed to ensure our codebase suited the workflow of a larger team and business. Recent customers are depending on us as they receive millions of visits per month and thousands of daily interactions to better serve their customers.
The top three findings after our investigation were:
- The codebase had become difficult to maintain
- With the combination of Agent and Admin functionality, the codebase had drastically increased in size
- Insufficient unit testing in place for existing code
- The current architecture didn’t lend itself well to a workflow that could allow multiple developers to carry out their work at the same time
- Combining our applications had resulted in areas to improve on web performance
- Slower loading times, and erratic input response times resulted in a less-than-optimal user experience
- The increase in project size was causing AngularJS performance issues
- Stylesheets had become inconsistent and unmanageable
- A mixture of third-party styles, Agent UI and Admin UI had resulted in an incongruent look-and-feel
- Dead CSS, Repeated CSS, and `!important` overrides had made styling throughout the application unpredictable and inextensible
Tackling the issue
Difficult to maintain codebase:
With the single User application codebase nearly doubling the size of our previously-separated codebases, we needed to figure out how to make working with the application more manageable on a day-to-day basis. Where previous architecture led us towards Models, Views and Controllers (MVC), we started to look towards Web Components as a solution.
Web Components allowed us to reinforce DRY (Don’t Repeat Yourself) principles through reuse of custom UI elements throughout the application. It also allowed us to encapsulate “Smart” and “Dumb” components, to separate rendering logic from service logic. With the implementation of “Dumb” components, we could also begin to implement an Altocloud styleguide, dictated by our designers, with a single definition of UI elements throughout all of our applications.
Optimizing Web Performance:
The root of our performance issues had stemmed from the codebase size increase, and how it had affected AngularJS throughout our application. Angularjs performance issues are well documented, and we needed to evaluate if continuing development with the framework would be detrimental to the application. Although creating a hybrid application may have been an option, recent releases of Angular provided solutions to the issues we were having through the new binding and web component features. Furthermore, creating a hybrid application to replace the framework in the future would be much simpler after the current application had been modularized, as components would be independent of each other.
Stylesheets were combined from the Agent UI and Admin UI when creating the unified Altocloud App. This caused many styles throughout the application to be duplicated, overridden, and in some cases, completely deprecated. Stylesheets had become difficult to manage, and styling was unpredictable in some cases in the application. To reduce the amount of duplicated style classes, and redefined styles, we decided to implement CSS Modules into our application. CSS modules would allow us to generate stylesheets that are independent for each web component. Common styling could be defined and inherited from our style guide, to ensure a consistent look and feel throughout the application, while reducing repeated styling and improving the maintainability of the codebase.
As a team, we integrated refactoring into our day-to-day tasks. Adding refactoring as technical debt to our product backlog would not have been ideal for our case. We iterate quite quickly at Altocloud, and putting new features and developments on hold until the application was refactored simply wasn’t an option. When developing a feature, we would refactor any files that required modification. With smaller refactors, we were able to carry out our work with less overhead, focus compatibility testing to the area in question, whilst gradually increasing the maintainability, performance and consistency of our application. Also, as time progressed, our gradual implementation allowed us to improve our process over time, if we encountered a better means of accomplishing our goals.
At present, we have more than half of our application codebase refactored to use web components, with ES6 modules and webpack. We have a much larger team working on a more manageable codebase, in tandem with other developers. Our stylesheets, unit tests and components are co-located, with specific dependencies to provide isolation, maintainability, and reusability for all our application code. As we progress further with these processes, we are working towards developing our style guide to ensure UI consistency across our application, whilst positioning ourselves to gradually improve on our existing application features.
Completely refactoring our main customer-facing application seemed like a massive undertaking six months ago, but the recent improvements in stability and consistency are something that our customers are really loving and that makes it all worthwhile.
If you're interested in seeing the results of our work, book a demo today with our Sales team.