
Hugo
In a previous post, I talked about simplification projects started in 2022.
I hope we will have the opportunity to address several of those on this blog. Meanwhile, in this post, I want to introduce you to one such project whose goal is to modernize all of our frontend technology using Nuxt .
I hope to give you an overview of our methodology, how we came to this decision and how we implemented it.
Context
To first understand what we are talking about, here are some important figures at the start of 2022:
The risk at this size is complexity and entanglement.
Some time ago we built a platform team whose objective is to create a product inside the product, intended for the other teams. In the literature, you will often hear about "platform as a product" because the work of such a team is to design the platform as one would build an external product. We will use exploration phases (discovery) including user interviews and intensive use of data.
In short, quantitative and qualitative. The idea being to be very concrete and pragmatic to avoid the "ivory tower architects" effect that may still exist here and there.
Their work encompasses various subjects:
For this team, simplification must be one of the main goal. What is simple is easy to explain and easy to use.
It must take into account change management, it is not enough to improve the platform, users must be helped during the transition. It can be through training, documentation, the use of standards and so on.
I was talking about quantitative above, it's important to rationalize things. We want to systematically have quantified criteria to start a project. Doing technique for technique's sake makes no sense. You have to show why you're doing it and set a goal for improvement. Without numbers, there are no goals. Without goals, nothing can be prioritized and there is no alignment.
Here for the context, now let's talk about the origins of the "Singapore" project, started within this team.
The origin of the project
Over time, the cognitive load of each developer has become significant given the size of the code base. The technological choices of the last 10 years are for some still very relevant, but for others it's less obvious, to be polite :)
And this is precisely the case for the front-end technologies that we use.
At the beginning of 2022 we make the following observation.
6 different technologies are used on the front-end side:
To understand, in 2012 we chose JSPs to do server side rendering (SSR) in order to be understood by indexing bots (Google, Bing) and therefore have good SEO. Later we introduced frameworks like AngularJS, later replaced by Vue.js to make portions of the page dynamic after loading. Finally, we totally used Vue.js for some single page applications (SPA).
All of this implies that there is a lot to know when developing on the front end, in particular because the same issues had to be addressed several times, for each technology.
If I take an example, on our developer documentation portal:
Another thing to know, most of the source code of frontend applications is included in the source code of backend applications in src/main/front directories and it is the role of the software factory to separate the artifacts at build time. But the developers themselves have to load everything into their IDE (intellij for many of us). With the volume of code and all the plugins needed to understand all the technologies, intellij suffers a lot. And when I say a lot...
On a daily basis, when working on the front-end of applications, there are also tools that run constantly, for example to make copies of files that have been modified (JSPs present in a common library) to the directory where the current application is running.
I skip over many other details, but what you need to remember:
The 1$ million question
At this point, I like to ask myself a simple question:
"What would be my choices if we were to create Malt from scratch in 2022? Could we do much better?"
Along with this question, I've had several positive experiences with jamstack stacks.
Jamstack is an architectural approach that decouples the web experience layer from data and business logic, improving flexibility, scalability, performance, and maintainability.
I was able to successfully test:
The answer to the above question seems obvious, in 2022 the most efficient standard approach would probably be to use a Jamstack approach.
Especially since here, we are talking about the frontend, but that also changes the development on the backend side. We are moving to an API-oriented paradigm. We no longer build business views because the presentation logic is now delegated to the frontend. We think in terms of API contracts and this can facilitate the work of our mobile team who will no longer need ad hoc development as much.
It also opens up other possibilities such as opening up our APIs externally.
To give back to Caesar what belongs to Caesar, this track had already been considered in 2018 by Mickael J. At that time, we imagined a solution using Nuxt in order to do Server side rendering and therefore meet SEO constraints. We weren't ready to invest so much in this change yet. Maybe we didn't have the necessary maturity either. Still, we have not started this project.
In 2022, however, our front end complexity has increased and we must simplify the "developer experience" at the risk of having big disappointments very soon otherwise.
However at this stage, it was still only an intuition. It had become necessary to study the feasibility of this project and to set quantified objectives for the result.
We decided to call the project "Singapore" which symbolically represents the departure of the island of Java (the JSP) towards the closest country on the Asian continent.
In a nutshell, what is Nuxt? It is a meta framework, i.e. it is a framework above another framework: vue.js
In particular, it provides the possibility of using several rendering modes:
And why Nuxt? The question could have arisen with Next.js which has the same objective in the React ecosystem. Next is older, seems more mature and has a very large community.
But we are very comfortable with Vue.js, a framework that we have been using for several years now. And in the vue.js ecosystem, Nuxt seemed to us to be the most mature.
After initiating the reflection, I started the preliminary study in July/August 2022.
The objective of the study was to verify that we could reproduce all of our current front-end applications. For example, we had to validate all our specificities on internationalization (management of plural forms with ICU), security (spring security taglibs), feature flipping (with ff4j) etc...
The second objective of the study was to define the criteria for success.
Finally, this phase was also the first step in a change management operation. The human aspect was crucial in this study phase in the sense that it had to involve the future sponsors of the project.
During this stage, a weekly meeting was set up to share progress, discuss technical points being studied or give demonstrations. A written and collaborative support (a google docs) was kept up to date throughout the duration of the study with all the discussions related to the prototypes, the minutes of meetings etc... This document is not an ADR strictly speaking (architecture decision record) but can be used to write it. In particular, it was used to write the developer documentation afterwards.
All non-sensitive prototypes have been released as open source to communicate with the Nuxt team:
https://gitlab.com/maltcommunity/public/singapore-prototypes
Among the points we covered during the study:
I would not go into detail here on each subject otherwise this post would be gigantic. But if there is particular interest in any of these items, it may be covered in a future post.
At the end of August, the study made it possible to validate the technical feasibility. In addition, the listed objectives were as follows:
However, these metrics changed afterwards.
Cycle times are currently poorly measured here. It's surprising, because it's arguably the most important metric of all, but actually we're not good enough yet to track it properly.
The reduction in build time must have had a lot to do with removing dependencies between front and back builds. This subject was addressed in parallel in another CI-related project (migration from maven to gradle).
Boot time is interesting, but we don't collect the metric on workstations.
For my part, I have some apps that could take between 100 and 200 seconds to start. But I have no way to demonstrate that this phenomenon is the same for everyone, and it is not true on all apps.
The time in integration and production is, moreover, totally different from the dev environment (largely linked to the datadog instrumentation and the sizing of the pods).
On decoupling, originally, we wonder how to measure it. And then we noted several possibilities:
A first real-life prototype will allow us to see things more clearly.
On September, a first application was migrated. The selection criteria for this first project were:
This first project was a SPA (without using SSR). It is an internal back office, a relatively simple app (12k lines of code). However, this application is interesting, because it uses JSP, small applications in vue2, and custom javascript. It therefore made it possible to demonstrate the feasibility of many outstanding points and to validate the general target architecture for a SPA in CSR (client side rendering).
The migration was done in "double run": The two apps coexisted with a routing mechanism performed by Traefik (our reverse proxy). The migration process also had to validate the way in which we could switch and go back in the event of problems.
In the meantime, the team has grown along the way and this will then allow us to move forward more quickly for the end of the year.
As I indicated above, one of the challenges in a project of this type is above all human. To improve the developer experience, we must not skimp on support.
In this context, I decided to completely revise our internal documentation portal for developers. This could be the subject of a post on its own, but in broad outline here are some important points:
Mid-October, a demo was made with the application migrated to Nuxt.
Here are some results:
Nuxt and Vue3 actually allow you to be much more concise than the JSP equivalent. View applications have also been simplified. But another explanation, and that's one of the benefits of rewrites like this. It was also an opportunity to detect unused features and remove them.
Regarding progress on accessibility, everything is not related to the fact of using nuxt but also to a massive use of the Malt design system while the old app used it little.
A second application was migrated between mid-October and December, this time very central since it is the home page and some content pages. This time, the SSR was mandatory.
Without going into detail, we use Prismic and nuxt prismic to create this content.
The results on this application are as follows:
So we see that for the moment, on average, we lighten the code base of front-end applications by more than 40% , which is above our initial expectations.
Startup time improves by 22% on staging and prod.
The surprise comes from the performance improvement, it was not an objective initially. The gains are very strong on the first app. They also exist on the second application however the "server response time" remains very high and we must work to improve it. However, for a first draft, it is very satisfactory.
To add a few things, 5 people were involved in the project full-time in December.
In January, 10.53% of applications were migrated.
The project, recognized as being strategic, is now a priority for the entire product team and will be implemented gradually throughout the year.
And that will conclude this first step. This post could be the subject of a follow-up later, either to give a progress report, or to go more in depth on certain very specific technical subjects.
No comments yet. Be the first to comment!